An index can be defined on more than one column of a table. For example, if you have a table of this form: インデックスは、テーブルの2つ以上の列に定義することができます。 例えば、以下のようなテーブルがあるとします。
CREATE TABLE test2 ( major int, minor int, name varchar );
(say, you keep your <filename class="directory">/dev</filename>
directory in a database...) and you frequently issue queries like:
(例えば、/dev
ディレクトリの内容をデータベースに保持していて)頻繁に下記のような問い合わせを発行するとします。
SELECT name FROM test2 WHERE major =constant
AND minor =constant
;
then it might be appropriate to define an index on the columns
<structfield>major</structfield> and
<structfield>minor</structfield> together, e.g.:
このような場合、major
およびminor
という2つの列に1つのインデックスを定義する方が適切かもしれません。
CREATE INDEX test2_mm_idx ON test2 (major, minor);
Currently, only the B-tree, GiST, GIN, and BRIN index types support
multiple-key-column indexes. Whether there can be multiple key
columns is independent of whether <literal>INCLUDE</literal> columns
can be added to the index. Indexes can have up to 32 columns,
including <literal>INCLUDE</literal> columns. (This limit can be
altered when building <productname>PostgreSQL</productname>; see the
file <filename>pg_config_manual.h</filename>.)
現在、B-tree、GiST、GINおよびBRINインデックス型でのみ、複数キー列インデックスをサポートしています。
複数キー列を持つことができるかどうかは、INCLUDE
列をインデックスに追加できるかどうかとは無関係です。
インデックスはINCLUDE
列を含めて最大32列まで持つことができます。
(この上限は、PostgreSQLを構築する際に変更可能です。
pg_config_manual.h
ファイルを参照してください。)
A multicolumn B-tree index can be used with query conditions that
involve any subset of the index's columns, but the index is most
efficient when there are constraints on the leading (leftmost) columns.
The exact rule is that equality constraints on leading columns, plus
any inequality constraints on the first column that does not have an
equality constraint, will always be used to limit the portion of the index
that is scanned. Constraints on columns to the right of these columns
are checked in the index, so they'll always save visits to the table
proper, but they do not necessarily reduce the portion of the index that
has to be scanned. If a B-tree index scan can apply the skip scan
optimization effectively, it will apply every column constraint when
navigating through the index via repeated index searches. This can reduce
the portion of the index that has to be read, even though one or more
columns (prior to the least significant index column from the query
predicate) lacks a conventional equality constraint. Skip scan works by
generating a dynamic equality constraint internally, that matches every
possible value in an index column (though only given a column that lacks
an equality constraint that comes from the query predicate, and only when
the generated constraint can be used in conjunction with a later column
constraint from the query predicate).
《マッチ度[52.363636]》複数列に対するB-treeインデックスをインデックス対象列の任意の部分集合を含む問い合わせ条件で使用することができます。
しかし、先頭側の(左側)列に制約がある場合に、このインデックスはもっとも効率的になります。
正確な規則は、先頭側の列への等価制約、および、等価制約を持たない先頭列への不等号制約がスキャン対象のインデックス範囲を制限するために使用されます。
これらの列の右側の列に対する制約は、このインデックス内から検査されます。
ですので、テーブルアクセスを適切に抑えますが、スキャンされるインデックスの範囲を減らしません。
例えば、(a, b, c)
に対するインデックスがあり、WHERE a = 5 AND b >= 42 AND c < 77
という問い合わせ条件があったとすると、
a
= 5かつb
= 42を持つ項目を先頭に、a
= 5となる最後の項目までのインデックスをスキャンしなければなりません。
c
>= 77を持つインデックス項目は飛ばされますが、スキャンを行わなければなりません。
このインデックスは原理上、 a
に対する制約を持たず、b
あるいはc
に制約に持つ問い合わせでも使用することができます。
しかし、インデックス全体がスキャンされますので、ほとんどの場合、プランナはインデックスの使用よりもシーケンシャルテーブルスキャンを選択します。
《機械翻訳》複数列B-ツリーインデックスは、問い合わせの列の任意のサブセットを含むインデックス条件で使用できますが、インデックスは先頭(左端)の列に制約がある場合に最も効率的です。
正確なルールは、先頭の列に対する等式制約、つまり等式制約を持たない最初のカラムに対するプラスの不等式制約が、スキャンされるインデックスの部分を制限するために常に使用されるということです。
これらの列の右側の列に対する制約はインデックスでチェックされるため、常にテーブルへの訪問を適切に保存しますが、スキャンする必要のあるインデックスの部分を必ずしも減らすとは限りません。
B-ツリーインデックススキャンがスキップスキャン最適化を効果的に適用できる場合は、インデックス検索を繰り返してインデックスをナビゲートするときに、すべてのカラム制約を適用します。
これにより、1つまたは複数の列(インデックスからの最下位のの前)に従来の等式がない場合でも、読み取られるインデックスの部分を減らすことができます。
は、内部的に動的等式を生成することによって機能します。
これは、内のすべての可能な値に一致します(ただし、に由来する等式を持たないが与えられた場合にのみ、生成されたが単位からの後の割引とともにで使用できる場合にのみ)。
インデックスカラムスキップ制約問い合わせ述語制約問い合わせ制約問い合わせ制約スキャンカラム制約カラム論理積述語述語カラム
For example, given an index on <literal>(x, y)</literal>, and a query
condition <literal>WHERE y = 7700</literal>, a B-tree index scan might be
able to apply the skip scan optimization. This generally happens when the
query planner expects that repeated <literal>WHERE x = N AND y = 7700</literal>
searches for every possible value of <literal>N</literal> (or for every
<literal>x</literal> value that is actually stored in the index) is the
fastest possible approach, given the available indexes on the table. This
approach is generally only taken when there are so few distinct
<literal>x</literal> values that the planner expects the scan to skip over
most of the index (because most of its leaf pages cannot possibly contain
relevant tuples). If there are many distinct <literal>x</literal> values,
then the entire index will have to be scanned, so in most cases the planner
will prefer a sequential table scan over using the index.
《機械翻訳》例では、インデックスon (x, y)
、および問い合わせ条件WHERE y = 7700
、B-ツリーインデックススキャンはスキップスキャン最適化を適用できる場合があります。
これは一般に、問い合わせプランナが、テーブルで利用可能なインデックスが与えられた場合、反復WHERE x = N AND y = 7700
可能性のあるすべての値N
または実際にインデックスに格納されているすべてx
の値の検索が可能な最速のアプローチであると想定している場合に発生します。
このアプローチは一般に、明確なx
値が非常に少ないため、プランナがインデックスの大部分に対してスキャンからスキップを想定している場合にのみ使用されます(リーフページの大部分には関連するタプルが含まれていない可能性があるため)。
明確なx
値が多数ある場合は、インデックス全体をスキャンする必要があるため、ほとんどの場合、プランナはインデックスよりシーケンシャルテーブルスキャンを優先します。
The skip scan optimization can also be applied selectively, during B-tree
scans that have at least some useful constraints from the query predicate.
For example, given an index on <literal>(a, b, c)</literal> and a
query condition <literal>WHERE a = 5 AND b >= 42 AND c < 77</literal>,
the index might have to be scanned from the first entry with
<literal>a</literal> = 5 and <literal>b</literal> = 42 up through the last
entry with <literal>a</literal> = 5. Index entries with
<literal>c</literal> >= 77 will never need to be filtered at the table
level, but it may or may not be profitable to skip over them within the
index. When skipping takes place, the scan starts a new index search to
reposition itself from the end of the current <literal>a</literal> = 5 and
<literal>b</literal> = N grouping (i.e. from the position in the index
where the first tuple <literal>a = 5 AND b = N AND c >= 77</literal>
appears), to the start of the next such grouping (i.e. the position in the
index where the first tuple <literal>a = 5 AND b = N + 1</literal>
appears).
《機械翻訳》スキップスキャン最適化は、問い合わせツリーからの少なくともいくつかの有用な制約を有するB-述語スキャン中に選択的に適用することもできる。
例の場合、インデックスon (a, b, c)
および問い合わせ条件が指定されている場合、インデックスはa
=5およびb
=42の最初のエントリからa
=5の最後のエントリまでスキャンする必要がある場合があります。
c
>=77のインデックスエントリはテーブルレベルでフィルタする必要はありませんが、インデックス内でスキップに利益をもたらす場合とそうでない場合があります。
スキップが行われると、スキャンは新しいインデックス検索を開始して、現在a
=5およびb
=Nグループ化の末尾(つまり、最初のタプルa = 5 AND b = N AND c >= 77
が表示されるインデックス内の位置)から、次のそのような(つまり、最初のa = 5 AND b = N + 1
が表示される内の位置)に自分自身を再配置します。
タプルグループ化スタートインデックスWHERE a = 5 AND b >= 42 AND c < 77
A multicolumn GiST index can be used with query conditions that involve any subset of the index's columns. Conditions on additional columns restrict the entries returned by the index, but the condition on the first column is the most important one for determining how much of the index needs to be scanned. A GiST index will be relatively ineffective if its first column has only a few distinct values, even if there are many distinct values in additional columns. 複数列GiSTインデックスは、インデックス対象列の任意の部分集合を含む問い合わせ条件で使用することができます。 他の列に対する条件は、インデックスで返される項目を制限します。 しかし、先頭列に対する条件が、インデックスのスキャン量を決定するもっとも重要なものです。 先頭列の個別値がわずかな場合、他の列が多くの個別値を持っていたとしても、相対的にGiSTインデックスは非効率的になります。
A multicolumn GIN index can be used with query conditions that involve any subset of the index's columns. Unlike B-tree or GiST, index search effectiveness is the same regardless of which index column(s) the query conditions use. 複数列GINインデックスは、インデックス対象列の任意の部分集合を含む問い合わせ条件で使用することができます。 B-treeやGiSTと異なり、インデックス検索の効果はどのインデックス列が問い合わせ条件で使用されているかに関係なく同じです。
A multicolumn BRIN index can be used with query conditions that
involve any subset of the index's columns. Like GIN and unlike B-tree or
GiST, index search effectiveness is the same regardless of which index
column(s) the query conditions use. The only reason to have multiple BRIN
indexes instead of one multicolumn BRIN index on a single table is to have
a different <literal>pages_per_range</literal> storage parameter.
複数列BRINインデックスは、インデックス対象列の任意の部分集合を含む問い合わせ条件で使用することができます。
GINと同様に、またB-treeやGiSTとは異なり、インデックス検索の効果はどのインデックス列が問い合わせ条件で使用されているかに関係なく同じです。
一つのテーブルに対して複数列BRINインデックスを一つ持つ代わりに複数のBRINインデックスを持つ唯一の理由は、異なるpages_per_range
ストレージパラメータを持つためです。
Of course, each column must be used with operators appropriate to the index type; clauses that involve other operators will not be considered. 当然ながら、インデックス種類に対して適切な演算子を各列に使用しなければなりません。 他の演算子を含む句は考慮されません。
Multicolumn indexes should be used sparingly. In most situations, an index on a single column is sufficient and saves space and time. Indexes with more than three columns are unlikely to be helpful unless the usage of the table is extremely stylized. See also <xref linkend="indexes-bitmap-scans"/> and <xref linkend="indexes-index-only-scans"/> for some discussion of the merits of different index configurations. 複数列インデックスは慎重に使用する必要があります。 多くの場合、単一列のインデックスで十分であり、また、その方がディスク領域と時間を節約できます。 テーブルの使用方法が極端に様式化されていない限り、4つ以上の列を使用しているインデックスは、不適切である可能性が高いでしょう。 異なるインデックス構成の利点に関するこの他の説明について11.5および11.9も参照してください。