Microsoft SQL Server已有非聚集复合索引时新增单字段索引能否提升性能?
关于Files表查询性能问题的解答
结论
新增的两个单列非聚集索引不会提升目标查询的性能,完全没有创建必要,反而会增加表的写入(INSERT/UPDATE/DELETE)开销。
原因说明
- 你当前已经存在的
IX_Files_CourierId_FileName复合唯一索引,已经是目标查询的最优索引:
目标查询SELECT COUNT(*) FROM Files WHERE MessengerId = 1 AND Filename = 'myfilename.xml'的过滤条件是两个字段的等值匹配,刚好完全匹配该复合索引的前缀顺序(MessengerId在前,FileName在后),而且该查询只需要统计行数,不需要读取其他列数据,属于覆盖索引查询,不需要回表查聚集索引,理论上性能已经是最优水平。 - 单列索引的效率远低于现有复合索引:
若走单独的Index_on_MessengerId索引,需要先筛选出所有MessengerId=1的行,再回表过滤FileName符合条件的行;若走单独的Index_on_FileName索引,需要先筛选出所有FileName='myfilename.xml'的行,再回表过滤MessengerId符合条件的行,两者的IO开销都远高于直接走现有复合索引。
生产环境查询慢的排查方向
开发环境运行快生产慢,和新增索引无关,优先排查以下问题:
- 先确认现有复合索引的字段是否正确:注意索引名是
IX_Files_CourierId_FileName,检查是否创建时误将MessengerId写成了其他字段(比如CourierId),导致索引无法匹配查询条件 - 检查生产环境该查询的实际执行计划,确认是否没有命中现有复合索引,误走了全表扫描
- 若执行计划异常,更新表的统计信息即可解决,执行语句:
UPDATE STATISTICS dbo.Files WITH FULLSCAN - 排查生产环境是否存在锁等待、阻塞的情况,导致查询超时
内容的提问来源于stack exchange,提问作者momlivirki
相关产品推荐
相关产品推荐

