Sql server 相对于聚集索引搜索的非聚集索引功能

Sql server 相对于聚集索引搜索的非聚集索引功能,sql-server,indexing,Sql Server,Indexing,问题很简单,但我们在索引/统计数据更新方面遇到了很多问题,在低负载环境中,这些问题并不总是导致正确的新执行计划,因此我需要在这里与大家一起检查以确保这一点 假设您有以下表格: /* TABLES: TABLE_A (PK_ID INT, [random columns], B_ID INT (INDEXED, and references TABLE_B.PK_ID)) TABLE_B (PK_ID INT, [random columns], C_ID INT (INDEXED, and r

问题很简单,但我们在索引/统计数据更新方面遇到了很多问题,在低负载环境中,这些问题并不总是导致正确的新执行计划,因此我需要在这里与大家一起检查以确保这一点

假设您有以下表格:

/*
TABLES: 
TABLE_A (PK_ID INT, [random columns], B_ID INT (INDEXED, and references TABLE_B.PK_ID))
TABLE_B (PK_ID INT, [random columns], C_ID INT (INDEXED, and references TABLE_C.PK_ID))
TABLE_C (PK_ID INT, [random columns])
*/

SELECT *
FROM TABLE_A A
JOIN TABLE_B B ON B.PK_ID = A.B_ID
JOIN TABLE_C C ON C.PK_ID = B.C_ID
WHERE A.randcolumn1 = 'asd' AND B.randcolumn2 <> 5
现在,由于B通过其聚集PK列连接到A,这是否意味着不会使用B.C_ID上的索引,因为信息已经通过B.PK_ID聚集索引返回?事实上,除非查询专门针对B.C_ID上的ID值,否则永远不会使用B.C_ID上的索引,这难道不是真的吗

这似乎是一个简单甚至愚蠢的问题,但我想绝对确保我做对了。我正在考虑对我们的索引进行调整,因为我们有很多未使用的索引,这些索引是从旧的数据模型继承而来的,它们在这样大小的数据库中占用了相当多的空间。经验表明,除了生产环境,我们无法完全信任任何环境中的执行计划,这是因为与测试环境相比,它的负载非常大,因此很难可靠地测试出来


谢谢

查询优化器可以随心所欲。它可以通过扫描C表来执行第二个连接,对于每一行,在B中查找匹配的行。您描述的索引将有助于查找

SQL Server提供统计信息来告诉您是否实际使用了索引:

select  db_name(ius.database_id) as Db
,       object_name(ius.object_id) as [Table]
,       max(ius.last_user_lookup) as LastLookup
,       max(ius.last_user_scan) as LastScan
,       max(ius.last_user_seek) as LastSeek
,       max(ius.last_user_update) as LastUpdate
from    sys.dm_db_index_usage_stats as ius
where   ius.[database_id] = db_id()
        and ius.[object_id] = object_id('YourTableName')
group by 
        ius.database_id
,       ius.object_id

如果索引未使用超过2个月,通常可以安全地删除它。

是否使用索引取决于您运行的查询。你能添加一些示例查询吗?该查询有一个示例查询。不使用B.C_ID索引的想法是问题的一部分。由于该列上的索引仅包含引用从B到C的FK_ID,并且该值永远不会被查询,它只是一个ID值,除了用作存储关系连接的ID之外,没有任何业务/编程用途,因此也不应使用该索引。谢谢!这很好,但是在这里使用相同的站点:我不应该对sys.dm\u db\u index\u usage\u stats的结果更感兴趣吗?现在就检查一下同意dm_db_index_usage_stats更好。它显示了一个索引是否用于读取,这就是您要查找的内容。我会更新答案。再次感谢,这已经揭示了许多有趣的事情,甚至超出了原来的问题D