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

时间:2010-01-08 17:38:16

标签: sql-server database performance indexing

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

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

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

4 个答案:

答案 0 :(得分:11)

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

答案 1 :(得分:4)

此脚本将查看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

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

但是如果你可以随着时间的推移监视这个查询的结果集,你肯定应该感觉到哪些索引没有被使用过。非常方便!

答案 2 :(得分:3)

如果您使用的是SQL Server 2005/2008,则应使用 Database Tuning advisor

您可以指定它运行一段给定的时间,它将收集有关正在使用的内容和不使用内容的统计信息。在运行结束时,它将提供一些非常有用的观察结果,说明如何优化索引策略。

答案 3 :(得分:1)

数据库调优向导在这里会很有帮助。使用Profiler在几个小时的过程中记录一组标准查询,并在调优向导中使用该跟踪文件来识别可能的冗余索引。