データベースに挿入が1つしかない場合、可能なすべての列の組み合わせにインデックスを付けるのは悪いことですか?


23

私は、大規模な選択クエリを必要とするレポートシステムに取り組んでいますが、データベースは一度しか入力されていません。データベース管理システムはMicrosoft SQL Server 2017です。このようなシステムを設計するより良い方法はおそらくありますが、理論的にこれにアプローチしましょう。

理論的に言えば:

  1. 非常に大きなデータベース(複数のテーブルに1億5000万行以上)がある場合
  2. また、データベースには一度しかデータが入力されないと想定できます。

可能なすべての列の組み合わせにインデックスを付けると、選択クエリのパフォーマンスに悪影響が出る可能性がありますか?


4
ほとんどの場合、可能な組み合わせはすべて非実用的です。より賢明なアプローチは、手動で非常に寛大にインデックスを作成することです。それは間違いなく理にかなっています。
usr

12
一貫性を保つために、タイトルまたは太字のテキストを言い換えることをお勧めします。一目で私は最高の投票答え「はい」で混乱していた
AAAAAA

1つのテーブルでは1億5000万行が大きくなりますが、データベースでは大きくありません。実際には、レポートシステムは可能な列の組み合わせの小さなサブセットのみを使用するため、少なくとも最初はキーの組み合わせに焦点を合わせ、その後必要に応じてより複雑にすることをお勧めします。
pojo-guy

回答:


36

はい、オプティマイザーには考慮すべきデータへの多くの追加アクセスパスがあるため、初期計画のコンパイル時間に影響します。

SQL Server 2017を使用し、一度ロードしてレポートを実行しているので、代わりにクラスター化された列ストアインデックスを使用しないのはなぜですか?

これは、考えられるすべての列の組み合わせにインデックスを付ける必要性に対する理想的なソリューションのようです。

列ストアインデックス-概要


Columnstoreも私が行くところですが、私は疑問に思っています...オプティマイザーはあなたが説明したものとは正反対に機能していませんか?私は、利用可能なインデックスをスキャンして、どれが有用かを「疑問に思う」代わりに、クエリをエグザミンし、そのクエリの完全なインデックスを「考え」て、存在するかどうかをチェックしますか?(そうでない場合、欠落したインデックスメッセージが生成されます。)私が正しい場合(推測するだけでわかりません)、インデックスの数が多い場合でも、いくつかのインデックスを持つよりも著しく長い時間はないはずです。そのうちの。
リモンカ

26

テーブルにN列がある場合、可能な列の組み合わせはすべて2 ^ N-1です(空のセットを削除します)。10列は1023インデックスを意味しますが、20列では1048575インデックスになります。ほとんどのインデックスは決して使用されませんが、オプティマイザーが考慮する必要があります。オプティマイザーが、より良いインデックスの代わりに、準最適なインデックスを選択する可能性があります。実際に有益なインデックスを見つけ出すのではなく、あらゆる種類のインデックスを生成する道をたどりません。

修正可能なインデックスの数を編集

ジェフはそれがよりさらに悪いことだ指摘2 ^ N(3,2,1)から(電源セット)(1,2,3)よりも明らかに異なっています。N列の場合、N個の方法ですべての列を含むインデックスの最初の位置を選択できます。N-1の方法での2番目の位置など。したがって、N!になります。フルサイズの異なるインデックス。これらのインデックスはいずれも、このセットの別のインデックスに含まれていません。また、完全なインデックスでカバーされないように、別の短いインデックスを追加することはできません。したがって、インデックスの数はN!です。したがって、10列の例は10になります!= 3628800インデックスおよび20(ドラムロール)2432902008176640000インデックスの場合。これはとてつもなく大きい数です。各インデックスに1 mmの部分にドットを配置すると、すべてのドットを通過するのに94日の光線が必要になります。全部、いけない;-)


6
さらに悪いことに、インデックス内の列の順序が重要になる場合があります。したがって、最大Nを取得できます!インデックス。
ジェフ

2
ただし、他のインデックスのプレフィックスであるインデックスは必要ありません。
バーマー

3
さらに悪いことです。すべてのインデックスにASCとDESCの組み合わせがあります。
ypercubeᵀᴹ

2
さらに悪いことに、INCLUDEインデックスがあります。
ypercubeᵀᴹ

2
そして、膨大な数の部分インデックス。
ypercubeᵀᴹ

7

いや

「すべて」をインデックス化することは実用的ではありませんが、「ほとんど」をインデックス化できます。

ここにあります。テーブルにN列がある場合、可能なインデックスの数はN!です。レッツは、あなただけではありません、テーブルには10個の列を持っていると言う10ことができインデックスを、しかし10!。つまり、1つのテーブルで3,628,800 ...です。これは多くのディスク容量、ディスクI / O、キャッシュ、シーク時間です。

どうして?いくつかの理由:

  • 通常、Lightwwightインデックスはキャッシュされます。これにより、インデックスが高速になります。300万個ある場合、それらはキャッシュされません。

  • SQLオプティマイザーは、特に結合を使用する場合、どちらを使用するかを決定するのに多くの時間を要する場合があります。

  • SQLオプティマイザーは、包括的なアルゴリズムの使用を断念し、代わりにヒューリスティックアルゴリズムを試してください。これは「最適ではない」場合があります。たとえば、PostgreSQLには、「8未満のテーブルクエリ」と「8を超えるテーブルクエリ」のさまざまなオプションがあります。

  • インデックスはヒープよりも軽いはずです。すべてのインデックスを作成している場合、インデックスはヒープと同じくらい重いものになります。これは、インデックスの目的を損なうものです。


数字は2 ^ 10ではありませんか?各列は、特定のインデックスに含まれるか、除外されます。順序は重要ですか?
-RemcoGerlich

2
@RemcoGerlichはい、順序が重要です。
ypercubeᵀᴹ

2

いいえ、おそらくSELECTクエリにマイナスの影響はありませんが、

  • ディスクの使用率が高くなります。
  • コストが大幅に増加しINSERTます。
  • ほとんどのインデックスは使用されません。
  • 多くのWHERE条件式は、主により複雑なものを含めて、依然としてインデックスを使用しません。
  • 必要なインデックスの数は、列の数とともに指数関数的に増加します。つまり、たとえば8列の場合、すべての可能な組み合わせに対して256のインデックスが必要です。

コンパイル時の問題を完全に引き起こす可能性があります。
エリックダーリン

@sp_BlitzErikアプリのORMに思いますか?
ペテルは、モニカを

いいえ、私の答えをご覧ください。
エリックダーリン

@sp_BlitzErikうわー、すてきです!
ペテルは、モニカを
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.