2014-01-09 101 views
0

这个问题很简单,但是我们有很多索引/统计更新问题并不总是在低负载环境中产生适当的新执行计划,我需要检查此问题与你们在这里确定。非聚集索引功能相对于聚集索引寻求

说你已经下表:

/* 
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列,应该不是意味着上B.C_ID 该索引将不会被使用作为信息已通过B.PK_ID聚集索引返回?事实上,除非查询专门针对该索引上的ID值,否则不会使用B.C_ID上的索引?

这可能看起来像一个简单而愚蠢的问题,但我想确保我得到这个权利。我正在考虑对索引进行调整,因为我们有很多未使用的索引是从旧数据模型继承而来的,并且它们在这个数据库中占据了相当大的空间。经验表明,除了生产之外,我们不能完全信任任何环境下的执行计划,这要归功于与测试环境相比的极端负载,这使得难以可靠地进行测试。

谢谢!

+0

是否使用索引取决于您运行的查询。你可以添加一些示例查询? – Andomar

+0

该查询有一个示例查询。 B.C_ID索引不会被使用的想法是问题的一部分。由于该列上的索引仅包含从B到C的引用的FK_ID,并且该值将永远不会被查询(它只是一个ID值,除了用作存储关系连接的ID之外,没有业务/编程用途),那么该指数也不应该被使用。 – Kahn

回答

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个月,它通常是安全的掉落。

+0

谢谢!这很好,但在这里使用相同的网站:http://www.mssqltips.com/sqlservertip/1239/how-to-get-index-usage-information-in-sql-server/我不应该更感兴趣来自sys.dm_db_index_usage_stats的结果?立即检查出来。 :) – Kahn

+0

同意'dm_db_index_usage_stats'更好。它显示了一个索引是否用于阅读,这就是你要找的。我会更新答案。 – Andomar

+0

并且再次感谢,甚至在原始问题之外已经揭示了一大堆有趣的事情。 :d – Kahn