web-dev-qa-db-ja.com

未使用のインデックスのベストプラクティス

このクエリに基づいて、総読み取り数が少ない(1または2のように0または0に非常に近い)と、大量または中程度のユーザー更新(このクエリで挿入または削除が見つからなかった)が見つかった場合、行数が多い場合、理論的にはインデックスを削除する必要があります。

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

ここで、この仮定の精度をクロスチェックしたいと思います。たとえば、1年以上存在しているが、一度も読み取られていないが、非常に更新されているインデックスは、悪い考えのようです。この仮定が無効であるシナリオはありますか?

11
DoubleVu

このDMVは、最後のSQL Serverの再起動以降の統計のみを維持します。ビューは完全に一掃され、すべてがゼロから始まります。

さらに重要なことに、このビューの特定のインデックスの行は、そのインデックスが再構築されるときに削除されます(再編成されたときは削除されません)。定期的なインデックスメンテナンスを実行している場合は、メンテナンスログを見て、削除を検討しているインデックスのいずれかが最近再構築されているかどうかを確認すると役立つ場合があります。

したがって、最後の再起動が先週のパッチの火曜日の更新または昨日のサービスパックであった可能性がある場合、最後の再起動以降の低い読み取りに基づいて決定を行うことは賢明ではない場合があります。または、最後の再構築以降、インデックスのメンテナンスを実行しているとき。月に1回、四半期に1回、または年に1回だけ実行されるレポートがあり、それは重要でせっかちな人によって実行されます。

さらに、あなたが知らない、将来起こるであろう何かのためのインデックスがあるかもしれません-税務シーズンのために準備されている一連のレポート、としましょう。

だから、私のアドバイスは:

DMVを使用してidentify削除する候補インデックス、しかしその決定をバブルで行わないでください-あなたがする必要があります現在使用されていないように見えても、ドロップする前にインデックスmightが存在する理由を判断するためのレッグワーク。

15
Aaron Bertrand

ビューには、最後の再起動以降の統計しかありません。サーバーを再起動する前に、メンテナンスウィンドウが毎月情報をキャプチャし始める前に、毎月朝に投稿したようなクエリを実行するジョブをセットアップすることを軽減するために、これにより、さらに時間をかけて傾向を見ることができました。また、不足している可能性のあるインデックスを探すために実行する2番目のクエリもありました。

考慮すべきもう1つのことは、他のインデックスがテーブルにあるものです。ほとんどまたは完全に別のインデックスの複製であるため、使用されていない可能性があります。はい。 SQLサーバーでは、2つの異なるが同一のインデックスを作成できるため、完全に冗長にすることができます。

また、そのインデックスが削除された場合、そのインデックスを使用したクエリのクエリプランがどうなるかを確認することもできます。使用する別のインデックスがあるか、フルテーブルスキャンにフォールバックする必要がある可能性があります。

何が実行されるかについてすべてを知ることは本当に難しく、結局頻繁に変化するため、インデックスは科学と同じくらい多くの芸術になります。

2