【问题标题】:Nonclustered index functionality relative to clustered index seek相对于聚集索引查找的非聚集索引功能
【发布时间】:2014-01-09 10:42:41
【问题描述】:

这个问题很简单,但是我们在索引/统计更新方面遇到了很多问题,但并不总是能在低负载环境中产生正确的新执行计划,我需要在这里与你们确认一下。

假设您有以下表格:

/*
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 聚集索引?实际上,除非查询专门针对该索引上的 ID 值,否则永远不会使用 B.C_ID 上的索引不是真的吗?

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

谢谢!

【问题讨论】:

  • 是否使用索引取决于您运行的查询。你能添加一些示例查询吗?
  • 那个查询有一个示例查询。不使用 B.C_ID 索引的想法是问题的一部分。由于该列上的索引仅包含从 B 到 C 的 FK_ID 引用,并且该值将永远被查询(它只是一个 ID 值,除了用作存储的 ID 之外没有任何业务/编程用途关系连接),那么也不应该使用索引。

标签: sql-server indexing


【解决方案1】:

查询优化器可以随心所欲。它可以通过扫描 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 个月未使用,通常可以安全地删除它。

【讨论】:

  • 谢谢!这很好,但在这里使用同一个站点:mssqltips.com/sqlservertip/1239/… 我不应该对 sys.dm_db_index_usage_stats 的结果更感兴趣吗?现在检查一下。 :)
  • 同意dm_db_index_usage_stats 更好。它显示索引是否用于读取,这就是您要查找的内容。我会更新答案。
  • 再次感谢,即使在原始问题之外,这已经揭示了许多有趣的事情。 :D
猜你喜欢
  • 2014-08-27
  • 2013-08-07
  • 2011-10-12
  • 2021-01-14
  • 2020-08-04
  • 2023-03-17
  • 1970-01-01
  • 2012-04-30
相关资源
最近更新 更多