私は、大規模な選択クエリを必要とするレポートシステムに取り組んでいますが、データが1度しか入力されないデータベースに基づいています。データベース管理システムはMicrosoft SQL Server 2017です。おそらく、このようなシステムを設計するためのより良い方法があるでしょうが、理論的にこれに取り組みましょう。
理論的に言えば:
可能なすべての列の組み合わせにインデックスを付けると、選択クエリのパフォーマンスに悪影響がありますか?
はい、オプティマイザには考慮すべきデータへの多くの追加アクセスパスがあるため、初期計画のコンパイル時間に影響します。
SQL Server 2017を使用していて、一度ロードしてレポートを実行しているので、代わりにクラスター化列ストアインデックスを使用しないでください。
これは、考えられるすべての列の組み合わせにインデックスを付ける必要がある場合の理想的なソリューションのようです。
テーブルに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日かかります。ありとあらゆる、いけない;-)
番号。
「すべて」にインデックスを付けることは実用的ではありませんが、「ほとんど」にインデックスを付けることができます。
つまりね。テーブルにN
列がある場合、可能なインデックスの数はN!
です。テーブルに10列あるとすると、10
の可能なインデックスだけでなく、10!
もできます。つまり... ,628,8 ...単一のテーブルで。これは、多くのディスク領域、ディスクI/O、キャッシュ、およびシーク時間です。
どうして?いくつかの理由:
通常、Lightwwightインデックスはキャッシュされます。 300万個ある場合、それらはキャッシュされません。
SQLオプティマイザは、特に結合を使用する場合に、どちらを使用するのが適切かを判断するのに長い時間がかかる場合があります。
SQLオプティマイザは、包括的なアルゴリズムの使用をあきらめて、代わりにヒューリスティックアルゴリズムを試す場合があります。これは「最適ではない」場合があります。たとえば、PostgreSQLには、「8未満のテーブルクエリ」と「8を超えるテーブルクエリ」のさまざまなオプションがあります。
インデックスはヒープよりも軽いことが想定されています。すべてのインデックスを作成している場合、インデックスはヒープと同じくらい重くなります...インデックスの目的に反する何か。
いいえ、おそらくSELECT
クエリに悪影響はありませんが、
INSERT
コストが増加します。WHERE
条件式は、インデックスを使用しません。主に、より複雑なインデックスです。