我有一个包含3列的表:ID, FirstName, Salary
。
现在我在ID上有一个聚集索引,当我执行这个查询时
select * from table where FirstName = 'a'
我使用聚簇索引扫描得到结果,并要求我在名字上添加非聚集索引。
当我在FirstName
上添加非聚集索引时,我会得到Index Seek
的结果。
我不明白为什么索引会寻求?由于非聚集索引不对数据进行排序,因此不应该是扫描吗?
答案 0 :(得分:1)
如果符合条件的行数(FirstName = 'a'
)足够小,那么SQL Server查询优化器将在非聚集索引中使用index seek
来查找行符合该条件,然后在第二步中使用Key lookup
进入主数据页以获取所有数据列(因为您使用的是SELECT * ..
)。
由优化器决定索引查找+键查找何时比聚簇索引扫描更有效。它主要取决于选择性 - 如果您的条件匹配太多行,则会发生聚簇索引扫描。
使查询优化器能够做出此类决策的“魔力”是关于SQL Server保留的数据和数据分布的统计信息 - 既包括索引,也包括其他选择性列。你的桌子。
如果统计信息已过期(因为您已经完成了大量更新并可能删除),那么查询优化器完全有可能使用低效/不合适的执行计划。这是主要的性能问题之一 - 始终确保您的统计数据得到良好维护和更新! (通过使用例如每晚或每周更新统计信息的维护计划 - 取决于您操作大块数据的频率)。