インデックスが必要か必要かを判断する方法


110

MS SQLデータベースで自動インデックスツールを実行しました(インデックス統計テーブルを参照するMicrosoftのスクリプトを変更しました- 自動自動インデックス作成)。統計から、作成する必要のあるインデックスの推奨事項のリストができました。

編集: 上記のインデックスは、データベースエンジンがインデックスに使用できるものを示すDMVから情報を取得し、スクリプトはTop xの推奨事項(シーク、ユーザーへの影響など)を取得し、テーブルに入れます。

(スクリプトが何をしているのかを明確にするために、下のラリー・コールマンの回答から部分的に取った上記の編集)

私はデータベース管理者が初めてであり、ネット上で簡単に検索したので、思い切って推奨インデックスを盲目的に追加することに消極的です。ただし、この分野での経験がないため、推奨事項が必要かどうかを判断する方法についてのアドバイスを探しています。

SQLプロファイラを実行する必要がありますか、それともテーブルをクエリするコードを調べる方が良いですか?他にアドバイスはありますか?



使用できないインデックスを確認してください。記事はあなたを助けるかもしれない:sqlshack.com/...
Shiwangini Shishulkar

回答:


80

私が使用ジェイソンStrateのインデックス解析スクリプト(旧場所を)。既存のインデックスがどれだけ使用されているか、および不足しているインデックスがどれだけ使用されているかがわかります。通常、テーブルのクエリの5%または10%以上を構成しない限り、インデックスを追加しません。

ただし、最も重要なことは、アプリケーションがユーザーに十分な速度で応答するようにすることです。

更新: Jason Strateの新しいスクリプトに関するインデックス分析ブログ記事(新しい場所)

ダブルアップデート:最近では、インデックス分析を実行するときにsp_BlitzIndex®を使用しています。


すべてのテーブルを分析するにはどのような変更が必要ですか?
MonsterMMORPG

1
sp_BlitzIndexは、特定のサイズを超えるすべてのテーブルを調べます。それを調整する方法を確認するには、ドキュメントを参照する必要があります。
ジェレマイアペシュカ

sp_BlitzIndexを実行するためのパラメーターは次のとおりです。brentozar.com
JackArbiter

トリプルアップデート?
Simon_Weaver

49

インデックスを扱う際に理解しておくべき重要な概念と用語がいくつかあります。シーク、スキャン、およびルックアップは、selectステートメントを通じてインデックスが利用される方法の一部です。キー列の選択性は、インデックスの有効性を決定するために不可欠です。

シークが発生するのは、SQL Server Query Optimizerが、要求したデータを見つける最良の方法がインデックス内の範囲をスキャンすることであると判断した場合です。通常、シークは、クエリがインデックスによって「カバー」されたときに発生します。つまり、シーク述語はインデックスキーにあり、表示された列はキーに含まれるか含まれます。SQL Serverクエリオプティマイザーが、データを見つけるための最良の方法はインデックス全体をスキャンしてから結果をフィルター処理することであると判断したときにスキャンが行われます。通常、ルックアップは、インデックスキーまたは含まれている列のいずれかに、要求されたすべての列がインデックスに含まれない場合に発生します。クエリオプティマイザーは、クラスター化キー(クラスター化インデックスに対して)またはRID(ヒープに対して)を使用して、他の要求された列を「ルックアップ」します。

通常、シーク操作は、より小さなデータセットを物理的にクエリするため、スキャンよりも効率的です。非常に小さな初期データセットなど、これが当てはまらない状況もありますが、それは質問の範囲を超えています。

ここで、インデックスの有効性を判断する方法を尋ねましたが、留意すべきことがいくつかあります。クラスター化インデックスのキー列は、クラスタリングキーと呼ばれます。これは、クラスター化インデックスのコンテキストでレコードを一意にする方法です。すべての非クラスター化インデックスには、必要に応じて検索を実行するために、デフォルトでクラスター化キーが含まれます。すべてのインデックスは、各DMLステートメントごとに挿入、更新、または削除されます。そうは言っても、selectステートメントのパフォーマンス向上とinsert、delete、およびupdateステートメントのパフォーマンスヒットとのバランスをとることが最善です。

インデックスの有効性を判断するには、インデックスキーの選択性を判断する必要があります。選択性は、合計レコードに対する個別のレコードの割合として定義できます。[person]テーブルに合計100個のレコードがあり、[first_name]列に90個の異なる値が含まれている場合、[first_name]列は90%の選択性があると言えます。選択性が高いほど、インデックスキーの効率が上がります。選択性を念頭に置いて、最も選択性の高い列をインデックスキーに最初に配置することをお勧めします。以前の[person]の例を使用して、95%の選択性を備えた[last_name]列があるとどうなりますか?[last_name]、[first_name]をインデックスキーとしてインデックスを作成します。

これは少し長めの答えだったと思いますが、インデックスがどれほど効果的であるかを判断する上で非常に多くの事柄があり、パフォーマンスの向上を比較検討する必要があることがたくさんあります。


1
上記のことについて強調したいだけです。インデックスは挿入/削除と更新を遅くします。大量のデータを一括で挿入する必要がある場合は、インデックスなしで済ませることをお勧めします(後で作成できますが、高速です)。
ニコラス・ド・フォントネ

[last_name]、[first_name]列のインデックスは、クエリがlast_nameとfirst_nameでフィルタリングする場合にのみ使用できると言うのは正しいでしょうか?first_nameのみでフィルタリングする場合、インデックスは使用できませんでしたか?
マジャー

良い答え-インデックスを作成するかどうかを決定する際には、カーディナリティーよりも選択性が重要です
リバースエンジニア

27

私は最近、BrentOzar Unltd http://www.brentozar.com/blitzindex/の人々から素晴らしい無料のスクリプトを発見しました

これにより、存在するインデックス、インデックスの使用頻度、クエリエンジンが存在しないインデックスを検索する頻度を適切に分析できます。

それは一般的に良いガイダンスです。時には、アイデアを少し過剰に示唆します。私はこれまで一般的に次のことを行ってきました。

  • 一度も読み取られていない(または月に50回未満の)インデックスを削除しました。
  • よく使用する外部キーとフィールドに関する最も明白なインデックスを追加しました。

すべての推奨インデックスを追加したわけではありませんが、クエリエンジンが代わりに他の新しいインデックスのいくつかを使用しているため、1週間後に戻って推奨されなくなったことがわかりました。

通常、次のインデックスは使用しないでください。

  • 非常に小さなテーブル(50〜200レコード未満):多くの場合、クエリエンジンは、インデックスの読み込み、読み取り、処理などよりもテーブルをスキャンする方が高速です。
  • 最初に言及した列のカーディナリティが低い列(http://en.wikipedia.org/wiki/Cardinality_(SQL_statements))のインデックスは避けてください。たとえば、性別フィールド(M / F)のインデックス付けはほとんど使用されません。テーブルをスキャンして、一致する〜50%を見つけるのも同じくらい実用的です。インデックス内でより具体的なもの([生年月日、性別]など)の後にリストされている場合は、より良い-すべての男性が特定の期間に生まれるようにすることができます。

クラスター化インデックスは優れています-通常、これらは主キーに基づいています。これらは、データベースエンジンがディスク上のデータを適切に整理するのに役立ちます。優れたクラスター化インデックスは多くの場合、テーブルが占有するスペースを減らすため、これを最大のテーブルで理解することは非常に重要です。

事前に構造化されていないヒープであったという理由だけで、いくつかのテーブルを900MBから400MBに削減しました。 http://msdn.microsoft.com/en-us/library/aa933131(v=sql.80).aspx

再編成/再構築

断片化されたインデックスを確認する必要があります。少し断片化しても大丈夫です。強迫観念しないでください!http://technet.microsoft.com/en-us/library/ms189858.aspx再編成と再構築の違いを知ってください!

定期的に確認する

クエリの変更、データボリュームの変更、新しい機能の追加、古い機能の削除。月に一度(または大容量の場合はもっと頻繁に)それらを見て、データベースを支援できる場所を探してください!

幾つ

最近のビデオでは、ブレントは(通常)大量の書き込みがあるテーブル(例:ordersテーブル)で5つ以上のインデックスを推奨します。 /www.youtube.com/watch?v=gOsflkQkHjg

全体

場合によります!

走行距離はデータベースによって異なります。(現在/将来の)大きなテーブルで、明白な(従業員の姓、注文日など)をカバーします。必要に応じて監視、確認、調整します。データベースを管理するときは、定期的なチェックリストの一部にする必要があります:)

お役に立てれば!


14

通常は、特定のワークロード(クエリ)を作成し、ワークロードに対する新しい各インデックスの影響を慎重にテストします。この反復プロセスには、実行計画の慎重な分析を常に含める必要があります。これにより、使用されているインデックスが明らかになります。クエリの分析のトピックは非常に長く、MSDNの専用の章である「クエリの分析」から始めるとよいでしょう。

ワークロードが複雑すぎる場合や、データベース設計の知識が不完全な場合は、データベースエンジンチューニングアドバイザーを使用して、ワークロードの自動分析を行い、いくつかのインデックスを提案します。もちろん、提案は慎重に分析し、影響をすぐに測定する必要があります。

したがって、私の考えに従えば、インデックスを追加して影響を測定することは、実際にはA / Bテストの場合にすぎません。ベースラインとしてインデックスなしでワークロードを実行し、インデックスを使用して実行し、測定し、比較しますベースラインを使用し、観測および測定されたメトリックに基づいて、影響が有益かどうかを判断します。ワークロードは最高品質のテストスイートですが、キャプチャされたワークロードのリプレイでもあります。「方法:トレースファイルをリプレイする」を参照してください。

より総合的な答えは、sys.dm_db_index_usage_statsビューを見て、インデックスがどのように利用されているかを確認することですが、それは通常、未知のワークロードでオンサイト分析を行うためのアプローチです(つまり、おそらく支援を求められるコンサルタントがこれから始めるでしょう)。


7

SQL 2005以降では、SQL ServerがありDMV、彼らが使用可能であった場合は、データベースエンジンがインデックスに使用する何を伝えるのを。ビューは、どの列をキー列にするか、どの列を含めるべきか、そして最も重要なことには、インデックスが何回使用されたかを知ることができます。

良い方法は、シークの数で欠落しているインデックスクエリをソートし、最初にトップインデックスを追加することを検討することです。

参照:公式MS DMVドキュメント


-1

それは、そのテーブルの使用方法に依存します。例えば、私は何度も読むテーブルを持っていると言うことができますが、更新と挿入はまれです。さらに、私は常にいくつかの外部キー列でテーブルをクエリします。読み取りクエリを高速化するために、その外部キーに対して(非クラスター化)インデックスを作成することは理にかなっています。しかし、欠点は、挿入、更新が遅くなることです。

クエリにかかっている時間を示す統計クエリはほとんどありません。最も遅いものから始めます。クエリ述語にインデックスがない場合、インデックスを作成すると役立ちます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.