未使用的索引最佳实践

Dou*_*eVu 11 index sql-server best-practices index-tuning

基于此查询,如果我看到少量的总读取(非常接近 0 或 0,如 1 或 2)和大量或中等数量的用户更新(我无法通过此查询找到插入或删除)行数很大,理论上我应该删除索引。

SELECT DISTINCT
    OBJECT_NAME(s.[object_id]) AS ObjectName
       , p.rows TableRows
       , i.name AS [INDEX NAME]
       , (user_seeks + user_scans + user_lookups) AS TotalReads
       , user_updates UserUpdates
FROM sys.dm_db_index_usage_stats s
    INNER JOIN sys.indexes i ON i.[object_id] = s.[object_id] 
        AND i.index_id = s.index_id 
    INNER JOIN sys.partitions p ON p.object_id = i.object_id
WHERE OBJECTPROPERTY(s.[object_id],'IsUserTable') = 1
       AND s.database_id = DB_ID()
       AND i.name IS NOT NULL
ORDER BY (user_seeks + user_scans + user_lookups) ASC
Run Code Online (Sandbox Code Playgroud)

我想在这里交叉检查这个假设的准确性。例如,一个已经存在一年多但从未被阅读过但高度更新的索引,似乎是一个坏主意。是否存在这种假设无效的情况?

Aar*_*and 15

此 DMV 仅维护自上次 SQL Server 重新启动以来的统计信息;视图完全消失,一切从头开始。

更重要的是,在重建该索引时(但不会在重新组织时),删除此视图中任何特定索引的行。如果您正在执行定期索引维护,查看维护日志并查看您正在考虑删除的任何索引最近是否已重建可能会很有用。

因此,基于自上次重启以来的低读取做出决定,当上次重启可能是针对上周的补丁星期二更新或昨天的服务包时,可能并不明智。或者当您执行索引维护时,自上次重建以来。可能有一份报告,每月只运行一次,或每季度一次,或一年一次,并且由一个重要且不耐烦的人运行。

此外,一个指数可能存在于你不知道的未来会发生的事情 - 比方说,为税收季节准备的一系列报告。

所以,我的建议是:

使用 DMV 来确定要删除的候选索引,但不要在泡沫中做出决定 - 您需要在删除索引之前确定为什么索引可能存在,即使它看起来当前没有被使用.