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