如何找到未使用的索引?


11

我正在数据仓库中工作。我有多达2亿条记录的表。其中一些表具有大约20多个索引(我无法提供为什么首先创建它们的原因)。这使维护这些索引的工作变得非常痛苦,并且直接影响了DWH导入工作的性能和运行时间。

如何找到每个表上使用最少的索引?(为了摆脱它们)


2
系统视图sys.dm_db_index_usage_stats提供了该信息。
Nenad Zivkovic

Answers:


10

试试这个脚本,它过去对我有帮助:

-- Unused Index Script
-- Original Author: Pinal Dave 
SELECT TOP 25
o.name AS ObjectName
, i.name AS IndexName
, i.index_id AS IndexID
, dm_ius.user_seeks AS UserSeek
, dm_ius.user_scans AS UserScans
, dm_ius.user_lookups AS UserLookups
, dm_ius.user_updates AS UserUpdates
, p.TableRows
, 'DROP INDEX ' + QUOTENAME(i.name)
+ ' ON ' + QUOTENAME(s.name) + '.'
+ QUOTENAME(OBJECT_NAME(dm_ius.OBJECT_ID)) AS 'drop statement'
FROM sys.dm_db_index_usage_stats dm_ius
INNER JOIN sys.indexes i ON i.index_id = dm_ius.index_id 
AND dm_ius.OBJECT_ID = i.OBJECT_ID
INNER JOIN sys.objects o ON dm_ius.OBJECT_ID = o.OBJECT_ID
INNER JOIN sys.schemas s ON o.schema_id = s.schema_id
INNER JOIN (SELECT SUM(p.rows) TableRows, p.index_id, p.OBJECT_ID
FROM sys.partitions p GROUP BY p.index_id, p.OBJECT_ID) p
ON p.index_id = dm_ius.index_id AND dm_ius.OBJECT_ID = p.OBJECT_ID
WHERE OBJECTPROPERTY(dm_ius.OBJECT_ID,'IsUserTable') = 1
AND dm_ius.database_id = DB_ID()
AND i.type_desc = 'nonclustered'
AND i.is_primary_key = 0
AND i.is_unique_constraint = 0
ORDER BY (dm_ius.user_seeks + dm_ius.user_scans + dm_ius.user_lookups) ASC

http://blog.sqlauthority.com/2011/01/04/sql-server-2008-unused-index-script-download/


10

我发现Brent Ozar Unlimited的免费 BlitzIndex脚本(由Kendra Little编写)是隔离未使用索引(以及有益添加的索引,复制其他索引工作的索引等)的最佳方法。

http://www.brentozar.com/blitzindex/

它会告诉您自上次重置统计计数(或创建/重新创建索引)以来已读取任何索引的次数。

我似乎记得布伦特·奥扎尔(Brent Ozar)在网络广播中说过,一个好的经验法则是,经常读取的表的索引不超过10个,对于静态/历史/存档数据不经常更改的表,索引不超过20个。

如果您仍然对导入速度有疑问,那么有时会不主动查询数据库(也许这不在办公时间)。删除索引,导入数据然后重新应用索引可能会有所帮助。(当然,统计信息将被重置。)这样做的原因是,随着每条记录的进入,索引将被更新,页面将被重新排序,这需要时间和磁盘I / O。建立索引,需要该表的单次扫描。

根据索引的类型和所涉及的数据,您可能没有硬性规定可以尝试。索引应随需求/查询的变化而定期检查。


1
我已经运行了该脚本,但希望有一个简单的指南来解释它。
IrishChieftain

0

尝试这个:

SELECT   OBJECT_NAME(S.[OBJECT_ID]) AS [OBJECT NAME], 
             I.[NAME] AS [INDEX NAME], 
             USER_SEEKS, 
             USER_SCANS, 
             USER_LOOKUPS, 
             USER_UPDATES 
    FROM     SYS.DM_DB_INDEX_USAGE_STATS AS S 
             INNER JOIN SYS.INDEXES AS I 
               ON I.[OBJECT_ID] = S.[OBJECT_ID] 
                  AND I.INDEX_ID = S.INDEX_ID 
    WHERE    OBJECTPROPERTY(S.[OBJECT_ID],'IsUserTable') = 1 

拉吉


0

我已经添加了上次使用的日期和代码,以删除到Raj的查询中。

SELECT   OBJECT_NAME(S.[OBJECT_ID]) AS [OBJECT NAME], 
             I.[NAME] AS [INDEX NAME], type_desc,
             coalesce(last_user_seek,last_user_scan,last_user_lookup,last_system_scan,last_system_seek,last_system_lookup) as LastUsed,
             USER_SEEKS, 
             USER_SCANS, 
             USER_LOOKUPS, 
             USER_UPDATES ,
             last_user_seek,last_user_scan,last_user_lookup,last_system_scan,last_system_seek,last_system_lookup,
             'drop index ['+I.[NAME]+'] on ['+OBJECT_NAME(S.[OBJECT_ID])+'];' as DropStatement
    FROM     SYS.DM_DB_INDEX_USAGE_STATS AS S 
             INNER JOIN SYS.INDEXES AS I 
               ON I.[OBJECT_ID] = S.[OBJECT_ID] 
                  AND I.INDEX_ID = S.INDEX_ID 
    WHERE    OBJECTPROPERTY(S.[OBJECT_ID],'IsUserTable') = 1 
    order by type_desc,coalesce(last_user_seek,last_user_scan,last_user_lookup,last_system_scan,last_system_seek,last_system_lookup) desc
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.