我印象中,像
CREATE NONCLUSTERED INDEX IX_Name_Age ON People
(
Name ASC,
Age ASC
)
不仅可用于 Select * From People WHERE Name = 'X' and Age = Y 之类的查询,还可用作 Select * From People WHERE Name = 'Z' 之类的单列索引
但是,在我迄今为止进行的几次测试中,情况似乎并非如此。例如,我在 Manufacturer/PartNumber 上有一个索引,以 Manufacturer 为首列,但 Select * WHERE Manufacturer = 'A' 仍然会进行表扫描。
我是否做错了什么或者解释错了什么或者我最初的假设是错误的?
答案1
如果 SQL Server 认为搜索最左边的列时使用非聚集索引的成本更低,那么它就会这样做。你的情况(我猜)的问题在于你执行的是 SELECT *,而不是仅指定你想要返回的列。如果你指定的列不在非聚集索引中,那么 SQL Server 将需要在索引查找之后执行键查找,然后返回到聚集索引(如果没有聚集索引,则返回到堆)以获取其余的列。
如果您只需要几列,那么请指定这些列,并将它们添加为现有索引中的包含列,然后 SQL Server 将开始使用该索引。
答案2
表中有多少行?如果表足够小,SQL Server 有时不会使用索引,因为从非聚集索引进行 RID/书签查找的开销可能超过避免表扫描的性能提升。只要您保持表上的统计信息更新,那么 SQL Server 就会在认为必要时求助于索引。