SQL Server - 如何确定索引是否未被使用?

Sql*_*yan 8 database sql-server indexing performance

我有一个高需求的事务数据库,我认为是过度索引.最初,它根本没有任何索引,因此为常见过程添加一些索引会产生巨大的差异.但是,随着时间的推移,我们已经创建了索引来加速单个查询,一些最流行的表上有10-15个不同的索引,在某些情况下,索引只是略有不同,或者是相同的列以不同的顺序.

是否有一种直接的方式来监视数据库活动并告诉是否有任何索引不再被命中,或者它们的使用百分比是多少?我担心创建索引是为了加速单个每日/每周查询,甚至是不再运行的查询,但每次数据更改时索引仍然必须保持最新.

对于高流量表,这是十几次/秒,我想消除压缩数据更新的索引,同时只提供边际改进.

Rem*_*anu 11

查看sys.dm_db_index_usage_stats中的用户搜索/扫描/查找次数和上次用户搜索/扫描/查找次数.这些统计信息在服务器启动时重置,因此您必须在服务器启动后检查并在运行时运行相关负载.


mar*_*c_s 5

该脚本将查看 DMV(动态管理视图)并找到那些尚未使用的索引。

DECLARE  @dbid INT

SELECT @dbid = DB_ID(DB_NAME())

SELECT   
    OBJECTNAME = OBJECT_NAME(I.OBJECT_ID),
    INDEXNAME = I.NAME,
    I.INDEX_ID
FROM     
    SYS.INDEXES I
JOIN 
    SYS.OBJECTS O ON I.OBJECT_ID = O.OBJECT_ID
WHERE    
    OBJECTPROPERTY(O.OBJECT_ID, 'IsUserTable') = 1
    AND I.INDEX_ID NOT IN 
       (SELECT S.INDEX_ID
        FROM SYS.DM_DB_INDEX_USAGE_STATS S
        WHERE S.OBJECT_ID = I.OBJECT_ID
        AND I.INDEX_ID = S.INDEX_ID
        AND DATABASE_ID = @dbid)
ORDER BY 
    OBJECTNAME, I.INDEX_ID, INDEXNAME ASC
Run Code Online (Sandbox Code Playgroud)

请注意 - DMV 是动态的- 例如,每次您重新启动 SQL Server 服务时,它们都会重置为“无”。如果您的服务器仅启动了几分钟,请不要检查这些!几乎所有的索引都会出现在你的结果集中......

但是,如果您可以随着时间的推移监视此查询的结果集,您绝对应该了解哪些索引从未被使用过。确实很方便!