4

このようなテーブルを想定しましょう

[KEY] [int] NOT NULL,
[INT1] [int] NULL,
[INT2] [int] NULL,
[INT3] [int] NULL,
[STR1] [varchar](20) NULL,
[STR2] [varchar](20) NULL,
[STR3] [varchar](20) NULL,

クエリは非常に柔軟ですが、常に次の形式のようになります。 SELECT KEY FROM [TABLE] WHERE...

検索条件は、単一の列で数回、ほとんどの場合、[int]タイプ、quesy asBETWEENまたは>=or <=、for 、でvarchar、常にクエリas=またはIN []。すべての条件はAND

クエリは常に同じ列に固定されるとは限らないためINDEX、すべての列に作成すると、パフォーマンスが向上するのでしょうか、それともまったく無駄になるのでしょうか。

4

3 に答える 3

5

すべての列にインデックスを作成するだけでなく、時間とリソースの無駄になります。

基本的に、私のアプローチは常に次のとおりです。

  1. 「通常の」テーブル(ステージングテーブルなどを除く)に適切なプライマリキーとクラスタリングキーを定義します。これはすでに大きなステップです。

  2. 非クラスター化インデックスを外部キー列に配置します-これらは、特にJOINの場合に非常に役立ちます

以上です!

それで:

  • あなたのシステムを観察してください-物事が遅いときを見てください
  • システムパフォーマンスの測定
  • サーバー側のトレースをキャプチャして、代表的なワークロードを取得します
  • そのワークロードを分析し、どのような追加のインデックスが役立つかを確認します
  • 微調整を行う-一度に1つずつ
  • 何度も測定して、システムパフォーマンスが向上した(または向上していない)かどうかを確認します

どのクエリが実際に一般的で頻繁に使用されるかを確認し、それらの頻繁なクエリにどのインデックスが有益であるかを確認するには、完全で代表的なワークロードが必要です。そうしないと、すべての間違ったクエリに対してインデックスヘルプを提供している可能性があり、実際に処理速度が低下する可能性があります...

非クラスター化インデックスが実際に役立つことはめったにないことに驚かれることでしょう。

インデックスを付けすぎないでください-インデックスがまったくない場合と同じくらい悪いですが、悪くはありません!あなたが持っているすべてのインデックスもその生涯にわたって維持される必要があるので、それはもっと悪いかもしれません...そして無料のランチはありません-ここでも...

キンバリー・トリップの優れたブログ投稿「インデックス」を参照してください。そうする必要があるとは限らないからです。トピックについて-非常に役立つ、多くの洞察。または、基本的に、キムがインデックスについてブログに書いたものをすべて読んでください。彼女はインデックスの女王であり、彼女のブログに投稿したものは通常、非常に役立ち、有益です。

さらに、SQL Server 2005以降ではDMV(動的管理ビュー)が提供されており、SQL Serverのクエリオプティマイザーの意見によれば、使用されていない(削除できる)インデックスや欠落しているインデックスを見つけることができます。詳細については、SQLServer-欠落しているインデックスと未使用のインデックスを検索するを参照してください。ただし、これらは動的なビューであることに注意してください。システムが起動するたびにリセットされ、完全に正確ではない可能性があります。すべてを実行するだけでなく、すべてを一粒の塩で処理し、実行内容を慎重に検討してください。文書化してください。 、状況が良くなるのではなく悪化した場合に元に戻すことができるように!

于 2012-05-05T21:25:31.570 に答える
2

一般的なインデックス設計ガイドラインで述べられているように、すべての列にインデックスを作成すると、パフォーマンスに影響を与える可能性があります。

テーブル内のインデックスの数が多いと、テーブル内のデータが変更されたときにすべてのインデックスを適切に調整する必要があるため、INSERT、UPDATE、DELETE、およびMERGEステートメントのパフォーマンスに影響します。

KEYまた、クエリで常に列を取得する場合は、インデックスに含まれる列として追加することを検討してください。これにより、テーブルへのアクセスを避けて、インデックスにアクセスする場合にのみ列を取得できます。ただし、SQL Server 2005以降のバージョンで使用できる、含まれている列を含むインデックスを作成することを忘れないでください。

最も頻繁に使用されるフィルターの組み合わせを調べて、次の点に注意して、複数列のインデックスをいくつか追加するだけです

インデックスに複数の列が含まれる場合は、列の順序を考慮してください。WHERE句で等しい(=)、より大きい(>)、より小さい(<)、またはBETWEEN検索条件で使用される列、または結合に参加する列を最初に配置する必要があります。追加の列は、明確さのレベルに基づいて、つまり、最も明確なものから最も明確でないものへと並べ替える必要があります。

于 2012-05-05T21:28:17.760 に答える
1

インデックスを挿入すると、正しい結果が直接得られる場合にクエリが部分的に役立ちますが、参照の局所性が向上し、読み取られるメモリの量が減ると、大きなメリットが得られます。

尋ねられた質問に対する答えは「それは依存する」です。それはあなたの質問に依存します。クエリされた主要な列が1つある場合、それは常に検索に表示されます。たとえばINT1、次の場所にインデックスを作成します。

 unique (INT1, INT2, INT3, REF)

そうすれば、INT1と他のフィールドの任意の組み合わせを参照するクエリが迅速になります。

また、INT1ではなくINT2を参照するクエリも、テーブル全体を読み取る必要がなく、インデックスのみを読み取る必要があるため、メリットがあります。INT2がインデックスの先頭にない場合でも、クエリには利点があります。DBはINT1をスキップしてINT2を確認するだけですが、テーブル全体を読み取ることなく、テーブルのINT2値を表示できます。

したがって、実際には、実行されるクエリをよりよく理解する必要があります。常に1つの列が表示される場合は、それをインデックスの先頭に配置します。別の列が頻繁に表示される場合、それは2番である必要があります。

両方が頻繁に表示される2つの列がある場合は、次のように実行できます。

unique (INT1, INT2, INT3, REF),
unique (INT2, INT1, INT3, REF)

次に、INT1が指定されていないが、INT2が指定されている場合、2番目のインデックスが使用されることを期待します。

ただし、あまり多くのインデックスを使用しないでください。インデックスは多くのディスク領域を占有する可能性があります。

結論:インデックスがある場合とない場合のクエリをテストします。10〜20の最小サンプルクエリを収集し、それらのIO時間とクロック時間をテストする必要があります。それが本当の答えを得る唯一の方法です。

于 2012-05-05T21:25:05.250 に答える