web-dev-qa-db-ja.com

すべての列を含むインデックスを作成することは理にかなっていますか

列のあるテーブルがあります

_ ID
 OtherTableId
 DataA
 DataB
 DataC
 DataD
_

すべての列が必要なときにOtherTableID INCLUDE (ID, DataA, DataB, DataC, DataD)にインデックスを作成することは意味がありますか、それとも_(OtherTableID)_だけにインデックスを作成するだけで十分ですか?

Includeを使用したインデックスはテーブルサイズを効果的に複製することを知っていますが、パフォーマンスが向上しますか?

クエリは:

_select * from Table Where OtherTableID = ?
_
5
LukLed

もし

  • クエリはこれらすべてのフィールドを使用し、
  • ソート順はクラスター化インデックスのソート順とは異なる必要があり、かつ
  • クラスタ化インデックスを変更することはできません。

列の順序が異なる追加(カバー)インデックスが役立つ場合があります。インデックスに関連するものと同様に、インデックスの数が増える(幅が広がる)と、書き込み/更新のパフォーマンスが低下します。これは、テーブルのサイズを事実上2倍にする場合に特に当てはまります。

他の列を含めずにOtherTableIdのみをインデックスに登録すると、インデックスは小さくなりますが、クエリは、高価なスキャンまたはソート演算子を含むクラスター化インデックスを使用するか、非クラスター化されたインデックス。一度に数行だけをクエリする場合は優れているかもしれませんが、テーブル全体をスキャンする場合は悲惨です。

これは一般的なアドバイスです。詳細については、質問を編集して、クエリ、テーブル定義、クエリプランを含めます。

4

これについてたくさんの情報がそこにありませんか? MySQLでSQLを学び、それをSQL Serverに組み込んだので、オープンソースのドキュメントの方が優れているかもしれません。

知っておくべき基本的なことは、インデックスの目的です。次に、それらを使用する必要があるかどうかを確認します。

基本的に、SQLステートメントのSELECT句以外の場所で列を使用するかどうかを自問してください。はいの場合は、インデックスを作成することを検討してください。そうでない場合は、理由がはるかに少なくなります。私の知る限り、SELECTにリストされている列は、JOIN、WHERE、GROUP BY、ORDER BYなどの列よりも「費用がかかりません」。

そうである場合、他の回答で述べたように、インデックス作成にはコストとメリットがあるため、次の質問への回答は困難です。インデックスを作成すると、インデックスを作成する列のサイズによってテーブルサイズが増加することは間違いです。サイズの増加は、インデックスのカーディナリティに比例すると思います。ただし、いずれの場合も、挿入の時間が長くなります。したがって、テーブルがめったに変更されず、主に読み取るだけの場合は、万が一のために、可能な限りすべてのインデックスを追加してください。

ただし、テーブルが頻繁に書き込まれる場合は、さらに注意してください。繰り返しますが、私の知識のほとんどはMySQLからのものですが、これらはここでも当てはまると思います。

  1. MySQLでは、おそらくSQL Serverでも、複合インデックスの最初の列に独自の個別のインデックスは必要ありません。
  2. 複合インデックスの列の順序は重要です。ステートメントで使用されている順序と一致する必要があります。
  3. クエリがめったに使用されない場合、インデックスを追加してそれを高速化するコストは、小さなメリットの価値がない場合があります。
  4. クエリが頻繁に使用され、テーブルが大きい場合は、インデックスを作成して高速化することを検討してください。

MySQLとSQL Serverの両方で、クエリ実行プランを表示できます。これを使用して、インデックスを作成する列を決定することができます(Googleを使用して詳細を検索します)

MySQLには「遅いクエリログ」があり、SQL Serverにも同様のものがあり、どのクエリが時間がかかりすぎているかを判断するのに役立ちます(Google it)

2
Buttle Butkus

以下は、2つのインデックスを持つ非常に一般的な2列のインデックスで、それぞれに2つの列がすべて含まれています。 http://mysql.rjweb.org/doc.php/index_cookbook_mysql#many_to_many_mapping_table

これは、多対多のマッピングテーブルです。これには、多対多の関係にある2つのテーブルに結合するための2つのIDがあります。

しかし、これは特別なケースです。

別の特別なケースがあります。 「カバーする」インデックスが何か知っていますか?これは、SELECTで言及されているすべての列を含むものです。しかし、カバリングインデックスを単に持つことは、テーブル自体を単に持つことと同じです。ただし、...カバリングインデックスの先頭にWHEREを最適化するのに役立つ列が含まれ、残りの列が「カバリング」するように追加されている場合、ビンゴ-あなたWHEREの支援と、必要なものがすべてインデックス内にあるためデータをヒットする必要がないという2つの利点を持つインデックスがあります。警告:インデックスに5つを超える列を含めることは「賢明ではありません」。

0
Rick James