2009-06-01 22 views
0

私は、プロダクション環境で使用されていないインデックスを検索するためのクエリを作成しましたが、last_user_updateカラムがインデックスがメンテナンスオーバヘッドだけだったかどうかが不思議ですそれを削除すると良いでしょう、またはインデックスが挿入/更新/削除ステートメントの実行に役立ったかどうか、その場合は削除したくありません。以下は、私が使用したいクエリです:MSSQL:last_user_updateはインデックスのパフォーマンスが低下することを意味しますか?

DECLARE @DBInfo TABLE 
(database_id int, object_id int, tablename nvarchar(200), indexname nvarchar(200), lastactivity datetime) 

DECLARE @command VARCHAR(5000) 

SELECT @command = 'Use [' + '?' + '] SELECT 
database_id, o.object_id, o.name, i.name as indexname, max(lastactivity) as lastactivity 
from (
    select database_id, object_id, index_id, max(last_user_seek) as lastactivity from sys.dm_db_index_usage_stats 
    WHERE object_id > 1000 
    GROUP BY database_id, object_id, index_id 
    UNION ALL 
    select database_id, object_id, index_id, max(last_user_scan) as lastactivity from sys.dm_db_index_usage_stats 
    WHERE object_id > 1000 
    GROUP BY database_id, object_id, index_id 
    UNION ALL 
    select database_id, object_id, index_id, max(last_user_lookup) as lastactivity from sys.dm_db_index_usage_stats 
    WHERE object_id > 1000 
    GROUP BY database_id, object_id, index_id 
    /*UNION ALL 
    select database_id, object_id, index_id, max(last_user_update) as lastactivity from sys.dm_db_index_usage_stats 
    WHERE object_id > 1000 
    GROUP BY database_id, object_id, index_id*/ 
) a 
inner join sys.objects o on a.object_id = o.object_id 
inner join sys.indexes i on i.object_id = a.object_id AND i.index_id = a.index_id 
where database_id = db_id() 
GROUP BY database_id, o.object_id, o.name, i.name 
order by lastactivity' 
INSERT INTO @DBInfo 
    (database_id, object_id, tablename, indexname, lastactivity) 
EXEC sp_MSForEachDB @command 

SELECT db_name(database_id) as dbname, tablename, indexname, lastactivity FROM @DBInfo 
where lastactivity < dateadd(day, -15, getdate()) or lastactivity is null 
order by db_name(database_id), tablename, indexname 

答えて

2

未使用のインデックスをチェックする際に列には何の意味もありません。

インデックスには最新の更新はないかもしれませんが、(テーブルスキャンを避けるために、または一般的なクエリをカバーするために)非常に便利です。このクエリは、インデックスが使用されている方法を説明します:

SELECT 
    o.name AS [object_name], 
    i.name AS index_name, 
    i.type_desc, 
    u.user_seeks, u.user_scans, 
    u.user_lookups, u.user_updates, 
    o.type 
FROM 
    sys.indexes i 
    JOIN 
    sys.objects o ON i.[object_id] = o.[object_id] 
    LEFT JOIN 
    sys.dm_db_index_usage_stats u ON i.[object_id] = u.[object_id] AND 
            i.index_id = u.index_id AND 
            u.database_id = DB_ID() 
WHERE 
    o.type IN ('U', 'V') AND 
    i.name IS NOT NULL 
ORDER BY 
    o.name, i.NAME; 

編集、コメントの後:

私はインデックスが使用されている方法を教えuser_seeks, user_scans, user_lookups and user_updates列を好みます。 FYI、私は上記のクエリを使用し、「system_updates」の列が含まれていますが、私はすべての値についてゼロを得た(SQL 2005、我々の前に良い効果にこれを使用していた50GBまたはので、データベース、)sys.dm_db_index_usage_stats

から

user_updatesカウンタは、 メンテナンス・レベルを示します。 は、基になるテーブルまたは ビューでの操作の挿入、更新、または削除によって発生します。このビューを使用すると、 は、アプリケーションによって軽く使用されるインデックスを特定することができます。 ビューを使用して、保守に負担がかかっている インデックスを確認することもできます。 オーバーヘッド。 メンテナンスのオーバーヘッドが発生するが、クエリには が使用されていないか、まれにクエリに使用されているのが であるインデックスを削除することを検討してください。彼らは使用かされているかどうか - -

だから、最後の文を使用すると、インデックスのダイナミックプロパティに興味があれば

+0

ありがとう:

SELECT object_name(object_id), d.*, s.* FROM sys.dm_db_missing_index_details d INNER JOIN sys.dm_db_missing_index_groups g ON d.index_handle = g.index_handle INNER JOIN sys.dm_db_missing_index_group_stats s ON g.index_group_handle = s.group_handle WHERE database_id = db_id() ORDER BY object_id 

は、未使用のインデックスを検索します。私はuser_updatesカラムが同じ質問を提起すると思います:それは悪くて良いですか? user_updatesがデータ変更のパフォーマンスを助けたり、それを傷つけたりしましたか? –

+0

詳細情報を追加しました。実際にこの列を使用していませんでした:主に用途を調べました。 – gbn

1

を使い方を見てと同様にアップデートすることを意味し、あなたが良いかもしれませんDMV - Dynamic Management Viewsでお問い合わせください。彼らはあなたにどのような指標が使われているか、どのくらいの頻度で良い情報があるのか​​を伝えるべきです。

また、実際にクエリオプティマイザの内部統計を使用して、a)パフォーマンスを向上させる潜在的なインデックスが欠けている可能性があり、b)未使用のインデックスがある可能性があることを示唆している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 
関連する問題