web-dev-qa-db-ja.com

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

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

理論的に言えば:

  1. 非常に大きなデータベースがある場合(複数のテーブルに1億5,000万行以上)
  2. また、データベースへの入力は1回だけであると想定できます。

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

24
Lopsided

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

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

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

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

36
Erik Darling

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

[〜#〜] edit [〜#〜]可能なインデックスの数を修正しました

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

27
Lennart

番号。

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

つまりね。テーブルにN列がある場合、可能なインデックスの数はN!です。テーブルに10列あるとすると、10の可能なインデックスだけでなく、10!もできます。つまり... ,628,8 ...単一のテーブルで。これは、多くのディスク領域、ディスクI/O、キャッシュ、およびシーク時間です。

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

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

  • SQLオプティマイザは、特に結合を使用する場合に、どちらを使用するのが適切かを判断するのに長い時間がかかる場合があります。

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

  • インデックスはヒープよりも軽いことが想定されています。すべてのインデックスを作成している場合、インデックスはヒープと同じくらい重くなります...インデックスの目的に反する何か。

7
The Impaler

いいえ、おそらくSELECTクエリに悪影響はありませんが、

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