web-dev-qa-db-ja.com

複合インデックスは、最初のフィールドのクエリにも適していますか?

フィールドABを持つテーブルがあるとします。 A + Bに対して定期的にクエリを実行するため、(A,B)に複合インデックスを作成しました。 Aのみのクエリも複合インデックスによって完全に最適化されますか?

さらに、Aにインデックスを作成しましたが、Postgresは引き続きAのみのクエリに複合インデックスを使用します。前の答えが正の場合、それは本当に問題ではないと思いますが、単一のAインデックスが使用可能な場合、デフォルトで複合インデックスを選択するのはなぜですか?

93
Luciano

確かにそうです。これについては、この関連する質問の下で詳しく説明しました。

スペースはMAXALIGNの倍数で割り当てられます。これは、通常、64ビットOSでは8バイト、32ビットOSでは(はるかに一般的ではありません)4バイトです。不明な場合は、 pg_controldata を確認してください。また、インデックス付けされた列のデータ型(一部は配置パディングが必要)および実際のコンテンツにも依存します。

たとえば、2つのinteger列(それぞれ4バイト)のインデックスは、通常、1つだけのインデックスとまったく同じサイズになり、さらに4バイトがアライメントパディングで失われます。

このような場合、クエリプランナーが(a,b)だけのインデックスと比較して、(a)のインデックスを使用することの欠点はありません。また、複数のクエリが同じインデックスを使用することは一般的に望ましいことです。共有されると、その(またはその一部)が(高速)キャッシュに存在する可能性が高くなります。

(a,b)のインデックスを既に保持している場合、 substantially より小さい場合を除いて、(a)だけに別のインデックスを作成しても意味がありません。 (b,a)(a) not trueも同じです。詳細については、最初の行のリンクをたどってください。

反対方向から来て、(a,b)にそのような追加のインデックスが必要な場合は、(a)だけに既存のインデックスを削除することを検討してください-可能であれば。 PKまたはUNIQUE制約のインデックスであるため、多くの場合不可能です。 Postgres 11以降では、代わりにb句を使用してINCLUDEを制約定義に追加するだけで済むかもしれません。 マニュアルの詳細。

Or代わりに(b,a)に新しいインデックスを作成して、bだけのクエリを追加でカバーします。等式条件の場合のみ、btreeインデックスのインデックス式の順序は重要ではありません。ただし、範囲条件が関係している場合はそうです。見る:

インデックスに追加の列を含めることには、潜在的なマイナス面があります。それ以外の場合は、アラインメントパディングで失われたスペースのみを使用します。

  • 追加の列が更新されるたびに、インデックスも更新が必要になるため、書き込み操作のコストが増加し、インデックスの膨張が増える可能性があります。
  • any インデックス列が関係している間は、テーブルのHOT更新(ヒープのみのタプル)はできません。

HOTアップデートの詳細:

オブジェクトのサイズを測定する方法:

92

あなたの質問によると、フィールドAとBのテーブルがあります。クエリが次の場合:

SELECT * FROM [YOUR TBL]
WHERE A='XXXX'

オプティマイザーは、抽出のランダムアクセスを回避するために複合インデックスを選択します。

3
BongSey