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 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 save visits to the table proper, but
they do not reduce the portion of the index that has to be scanned.
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 would 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 would be
skipped, but they'd still have to be scanned through.
This index could in principle be used for queries that have constraints
on <literal>b</literal> and/or <literal>c</literal> with no constraint on <literal>a</literal>
— but the entire index would have to be scanned, so in most cases
the planner would prefer a sequential table scan over using the index.
複数列に対する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
に制約に持つ問い合わせでも使用することができます。
しかし、インデックス全体がスキャンされますので、ほとんどの場合、プランナはインデックスの使用よりもシーケンシャルテーブルスキャンを選択します。
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も参照してください。