バージョンごとのドキュメント一覧

CREATE INDEX

CREATE INDEX <refpurpose>define a new index</refpurpose> — 新しいインデックスを定義する

概要

CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] name ] ON [ ONLY ] table_name [ USING method ]
    ( { column_name | ( expression ) } [ COLLATE collation ] [ opclass [ ( opclass_parameter = value [, ... ] ) ] ] [ ASC | DESC ] [ NULLS { FIRST | LAST } ] [, ...] )
    [ INCLUDE ( column_name [, ...] ) ]
    [ NULLS [ NOT ] DISTINCT ]
    [ WITH ( storage_parameter [= value] [, ... ] ) ]
    [ TABLESPACE tablespace_name ]
    [ WHERE predicate ]

説明

<title>Description</title>

<command>CREATE INDEX</command> constructs an index on the specified column(s) of the specified relation, which can be a table or a materialized view. Indexes are primarily used to enhance database performance (though inappropriate use can result in slower performance). CREATE INDEXは、指定したリレーションの指定した列(複数可)に対するインデックスを作ります。 リレーションとしてテーブルまたはマテリアライズドビューを取ることができます。 インデックスは主にデータベースの性能を向上するために使われます (しかし、インデックスの不適切な使用は性能の低下につながる可能性があります)。

The key field(s) for the index are specified as column names, or alternatively as expressions written in parentheses. Multiple fields can be specified if the index method supports multicolumn indexes. インデックスのキーフィールドは、列名、または括弧に囲まれた式として指定されます。 インデックスメソッドが複数列に対するインデックスをサポートする場合は、複数のフィールドを指定できます。

An index field can be an expression computed from the values of one or more columns of the table row. This feature can be used to obtain fast access to data based on some transformation of the basic data. For example, an index computed on <literal>upper(col)</literal> would allow the clause <literal>WHERE upper(col) = 'JIM'</literal> to use an index. インデックスのフィールドとして、テーブル行の1つ以上の列の値から計算する式を指定できます。 この機能は、元のデータに何らかの変換を加えた値を基とするデータへの高速なアクセスを行う手段として使用することができます。 例えば、upper(col)という計算に基づくインデックスがあれば、WHERE upper(col) = 'JIM'という句ではインデックスを使用することができます。

<productname>PostgreSQL</productname> provides the index methods B-tree, hash, GiST, SP-GiST, GIN, and BRIN. Users can also define their own index methods, but that is fairly complicated. PostgreSQLはB-tree、ハッシュ、GiST、SP-GiST、GIN、BRINのインデックスメソッドを用意しています。 ユーザが独自にインデックスメソッドを定義することもできますが、これはかなり複雑です。

When the <literal>WHERE</literal> clause is present, a <firstterm>partial index</firstterm> is created. A partial index is an index that contains entries for only a portion of a table, usually a portion that is more useful for indexing than the rest of the table. For example, if you have a table that contains both billed and unbilled orders where the unbilled orders take up a small fraction of the total table and yet that is an often used section, you can improve performance by creating an index on just that portion. Another possible application is to use <literal>WHERE</literal> with <literal>UNIQUE</literal> to enforce uniqueness over a subset of a table. See <xref linkend="indexes-partial"/> for more discussion. WHERE句が存在する場合、部分インデックスが作成されます。 部分インデックスは、テーブルの一部、通常は、テーブルの中でよりインデックスが有用な部分のみのエントリを持つインデックスです。 例えば、請求済みの注文と未請求の注文を情報として持つテーブルがあり、テーブル全体における未請求の注文の割合が小さく、かつ、頻繁に使用される場合、未請求の注文のみにインデックスを作成することで性能を向上できます。 部分インデックスのその他の利用方法として、UNIQUE付きのWHEREを使用して、テーブルの部分集合に一意性を強制する例が考えられます。 詳細は11.8を参照してください。

The expression used in the <literal>WHERE</literal> clause can refer only to columns of the underlying table, but it can use all columns, not just the ones being indexed. Presently, subqueries and aggregate expressions are also forbidden in <literal>WHERE</literal>. The same restrictions apply to index fields that are expressions. WHERE句内の式では、元となるテーブルの列のみを参照できます。 しかし、インデックスを付加する列だけではなく、全ての列を使用することができます。 また、現在、副問い合わせと集約式については、WHEREで使用することができません。 同一の制限は、式で表されたインデックスのフィールドにも適用されます。

All functions and operators used in an index definition must be <quote>immutable</quote>, that is, their results must depend only on their arguments and never on any outside influence (such as the contents of another table or the current time). This restriction ensures that the behavior of the index is well-defined. To use a user-defined function in an index expression or <literal>WHERE</literal> clause, remember to mark the function immutable when you create it. インデックスの定義で使用される全ての関数と演算子は、不変(immutable)でなければなりません。 つまり、結果は入力引数にのみに依存し、(他のテーブルの内容や現時刻などの)外部からの影響を受けてはなりません。 この制限によって、インデックスの動作が十分定義されていることが保証されます。 インデックス式やWHERE句にユーザ定義の関数を使用する場合、関数を作成する際、IMMUTABLE(不変)オプションを付けることを忘れないでください。

パラメータ

<title>Parameters</title>
UNIQUE

Causes the system to check for duplicate values in the table when the index is created (if data already exist) and each time data is added. Attempts to insert or update data which would result in duplicate entries will generate an error. インデックスを(既にデータがある状態で)作成する時、およびテーブルにデータを追加する時に、テーブル内の値が重複していないかを検査します。 重複エントリを生じるデータの挿入または更新はエラーとなります。

Additional restrictions apply when unique indexes are applied to partitioned tables; see <xref linkend="sql-createtable" />. 一意性インデックスがパーティションテーブルに適用されるときには、追加的な制限が適用されます。CREATE TABLEを参照してください。

CONCURRENTLY

When this option is used, <productname>PostgreSQL</productname> will build the index without taking any locks that prevent concurrent inserts, updates, or deletes on the table; whereas a standard index build locks out writes (but not reads) on the table until it's done. There are several caveats to be aware of when using this option &mdash; see <xref linkend="sql-createindex-concurrently"/> below. このオプションを使用すると、PostgreSQLは、対象テーブルに対する同時挿入、更新、削除を防止するようなロックを獲得せずにインデックスを作成します。 通常のインデックス作成処理では、完了するまで対象テーブルへの書き込みはできません(読み取りは可能です)。 このオプションを使用する際に注意しなければならない点が複数あります。 下記のインデックスの同時作成を参照してください。

For temporary tables, <command>CREATE INDEX</command> is always non-concurrent, as no other session can access them, and non-concurrent index creation is cheaper. 一時テーブルに対してはCREATE INDEXは常に同時作成ではありません。他のセッションはアクセスできませんし、同時でないインデックス作成の方がより安価だからです。

IF NOT EXISTS

Do not throw an error if a relation with the same name already exists. A notice is issued in this case. Note that there is no guarantee that the existing index is anything like the one that would have been created. Index name is required when <literal>IF NOT EXISTS</literal> is specified. 同じ名前のリレーションが既に存在している場合にエラーとしません。 この場合、注意が発行されます。 既存のインデックスが、作成されようとしていたものと類似のものである保証は全くないことに注意してください。 IF NOT EXISTSを指定する場合はインデックス名が必須です。

INCLUDE

The optional <literal>INCLUDE</literal> clause specifies a list of columns which will be included in the index as <firstterm>non-key</firstterm> columns. A non-key column cannot be used in an index scan search qualification, and it is disregarded for purposes of any uniqueness or exclusion constraint enforced by the index. However, an index-only scan can return the contents of non-key columns without having to visit the index's table, since they are available directly from the index entry. Thus, addition of non-key columns allows index-only scans to be used for queries that otherwise could not use them. オプションのINCLUDE句は非キー列としてインデックスに含める列のリストを指定します。 非キー列をインデックススキャンの検索条件に使うことはできません。また、インデックスで何であれ一意性制約や排他制約を強制する目的に対しても無視されます。 しかしながら、インデックスオンリースキャンは、インデックスエントリから値を直接得ることができるので、インデックスのテーブルを見に行く必要なく、非キー列の内容を返すことができます。 このように非キー列の追加は、そうでないとできないインデックスオンリースキャンを利用可能にします。

It's wise to be conservative about adding non-key columns to an index, especially wide columns. If an index tuple exceeds the maximum size allowed for the index type, data insertion will fail. In any case, non-key columns duplicate data from the index's table and bloat the size of the index, thus potentially slowing searches. Furthermore, B-tree deduplication is never used with indexes that have a non-key column. インデックスに非キー列を加えることには、特に幅広の列については、保守的であるのが賢明です。 インデックス列がインデックス型で許される最大サイズを超えた場合、データ挿入は失敗してしまいます。 いかなる場合でも、非キー列はインデックスのテーブルからデータを複製して、インデックスのサイズを膨張させます。よって、潜在的に検索を遅くします。 さらに、非キー列を持つインデックスではB-tree重複排除は決して使われません。

Columns listed in the <literal>INCLUDE</literal> clause don't need appropriate operator classes; the clause can include columns whose data types don't have operator classes defined for a given access method. INCLUDE句にある列リストは適合した演算子クラスを必要としません。ここには与えられたアクセスメソッドに対して定義された演算子クラスを持たないデータ型の列を含めることができます。

Expressions are not supported as included columns since they cannot be used in index-only scans. インデックスオンリースキャンで使うことができないため、INCLUDEする列に式は対応していません。

Currently, the B-tree, GiST and SP-GiST index access methods support this feature. In these indexes, the values of columns listed in the <literal>INCLUDE</literal> clause are included in leaf tuples which correspond to heap tuples, but are not included in upper-level index entries used for tree navigation. 今のところ本機能はB-tree、GiST、SP-GiSTインデックスアクセスメソッドに対応しています。 これらのインデックスではINCLUDE句にリストされた列の値は、ヒープタプルに対応するリーフタプルに含まれますが、ツリーを辿るのに使われる上位レベルのインデックスエントリには含まれません。

name

The name of the index to be created. No schema name can be included here; the index is always created in the same schema as its parent table. The name of the index must be distinct from the name of any other relation (table, sequence, index, view, materialized view, or foreign table) in that schema. If the name is omitted, <productname>PostgreSQL</productname> chooses a suitable name based on the parent table's name and the indexed column name(s). 作成するインデックスの名前です。 この名前には、スキーマ名を含めることはできません。 インデックスは、常にその親テーブルと同じスキーマに作成されます。 この名前は、同じスキーマ内にある他のリレーション(テーブル、シーケンス、インデックス、ビュー、マテリアライズドビュー、外部テーブル)と異なるものでなければなりません。 この名前を省略すると、PostgreSQLはその親テーブルの名前とインデックス付けされる列名に基づいた適切な名前を選びます。

ONLY

Indicates not to recurse creating indexes on partitions, if the table is partitioned. The default is to recurse. テーブルがパーティションテーブルであっても、パーティションにインデックス作成を再帰的に実行しないことを示します。 デフォルトでは再帰実行します。

table_name

The name (possibly schema-qualified) of the table to be indexed. インデックスを作成するテーブルの名前です(スキーマ修飾名の場合もあります)。

method

The name of the index method to be used. Choices are <literal>btree</literal>, <literal>hash</literal>, <literal>gist</literal>, <literal>spgist</literal>, <literal>gin</literal>, <literal>brin</literal>, or user-installed access methods like <link linkend="bloom">bloom</link>. The default method is <literal>btree</literal>. 使用するインデックスメソッドの名前です。 btreehashgistspgistginbrin、またはbloomのようなユーザがインストールしたアクセスメソッドから選択します。 デフォルトのメソッドはbtreeです。

column_name

The name of a column of the table. テーブルの列の名前です。

expression

An expression based on one or more columns of the table. The expression usually must be written with surrounding parentheses, as shown in the syntax. However, the parentheses can be omitted if the expression has the form of a function call. テーブル上の1つ以上の列を使用した式です。 通常この式は、構文で示した通り括弧で囲む必要があります。 しかし、式が関数呼び出し形式になっている場合は括弧を省略することができます。

collation

The name of the collation to use for the index. By default, the index uses the collation declared for the column to be indexed or the result collation of the expression to be indexed. Indexes with non-default collations can be useful for queries that involve expressions using non-default collations. インデックスで使用する照合順序の名前です。 デフォルトではインデックスはインデックス付け対象の列で宣言された照合順序またはインデックス付け対象の式の結果の照合順序を使用します。 デフォルト以外の照合順序を使用する式を含む問い合わせで、デフォルト以外の照合順序を持つインデックスが有用になるかもしれません。

opclass

The name of an operator class. See below for details. 演算子クラスの名前です。 詳細は下記を参照してください。

opclass_parameter

The name of an operator class parameter. See below for details. 演算子クラスパラメータの名前です。 詳細は下記を参照してください。

ASC

Specifies ascending sort order (which is the default). 正方向のソート順を指定します(これがデフォルトです)。

DESC

Specifies descending sort order. 逆方向のソート順を指定します。

NULLS FIRST

Specifies that nulls sort before non-nulls. This is the default when <literal>DESC</literal> is specified. NULLを非NULLより前にソートすることを指定します。 これはDESCが指定された場合のデフォルトです。

NULLS LAST

Specifies that nulls sort after non-nulls. This is the default when <literal>DESC</literal> is not specified. NULLを非NULLより後にソートすることを指定します。 これはDESCが指定されない場合のデフォルトです。

NULLS DISTINCT
NULLS NOT DISTINCT

Specifies whether for a unique index, null values should be considered distinct (not equal). The default is that they are distinct, so that a unique index could contain multiple null values in a column. 一意性インデックスのNULL値を個別(等しくない)とみなすかどうかを指定します。 デフォルトでは、NULL値は個別であるため、一意性インデックスは1つの列に複数のNULL値を含むことができます。

storage_parameter

The name of an index-method-specific storage parameter. See <xref linkend="sql-createindex-storage-parameters"/> below for details. インデックスメソッド固有の格納パラメータの名前です。 詳細は下記のインデックス格納パラメータを参照してください。

tablespace_name

The tablespace in which to create the index. If not specified, <xref linkend="guc-default-tablespace"/> is consulted, or <xref linkend="guc-temp-tablespaces"/> for indexes on temporary tables. インデックスを生成するテーブル空間です。 指定されなかった場合、default_tablespace、もし一時テーブル上のインデックスであれば、temp_tablespacesが考慮されます。

predicate

The constraint expression for a partial index. 部分インデックス用の制約式です。

<refsect2 id="sql-createindex-storage-parameters" xreflabel="Index Storage Parameters">

インデックス格納パラメータ

<title>Index Storage Parameters</title>

The optional <literal>WITH</literal> clause specifies <firstterm>storage parameters</firstterm> for the index. Each index method has its own set of allowed storage parameters. The B-tree, hash, GiST and SP-GiST index methods all accept this parameter: WITH句を使うと、インデックスの格納パラメータを指定できます。 インデックスメソッドはそれぞれ固有の設定可能な格納パラメータを持ちます。 B-tree、ハッシュ、GiSTおよびSP-GiSTといったインデックスはすべて次のパラメータを受け付けます。

fillfactor (integer) #

The fillfactor for an index is a percentage that determines how full the index method will try to pack index pages. For B-trees, leaf pages are filled to this percentage during initial index builds, and also when extending the index at the right (adding new largest key values). If pages subsequently become completely full, they will be split, leading to fragmentation of the on-disk index structure. B-trees use a default fillfactor of 90, but any integer value from 10 to 100 can be selected. インデックス用のフィルファクタは割合(パーセント)で、インデックスメソッドがインデックスページをまとめ上げる時にどの程度ページを使用するかを決定するものです。 B-treeでは、リーフページは初期インデックス構築時と右側(新しい最大キー値を追加する方向)にインデックスを拡張する時にこの割合分までページを使用します。 その後ページすべてが完全に使用されると分割され、ディスク上のインデックスの構造が断片化していきます。 B-treeのデフォルトのフィルファクタは90ですが、10から100までの任意の整数値を設定することができます。

B-tree indexes on tables where many inserts and/or updates are anticipated can benefit from lower fillfactor settings at <command>CREATE INDEX</command> time (following bulk loading into the table). Values in the range of 50 - 90 can usefully <quote>smooth out</quote> the <emphasis>rate</emphasis> of page splits during the early life of the B-tree index (lowering fillfactor like this may even lower the absolute number of page splits, though this effect is highly workload dependent). The B-tree bottom-up index deletion technique described in <xref linkend="btree-deletion"/> is dependent on having some <quote>extra</quote> space on pages to store <quote>extra</quote> tuple versions, and so can be affected by fillfactor (though the effect is usually not significant). 多くの挿入や更新が予想されるテーブルのB-treeインデックスでは、(テーブルへの一括ロードに続く)CREATE INDEXの時にフィルファクタを低い値に設定することで恩恵に与れるかもしれません。 50から90の範囲の値は、B-treeインデックスの初期の段階でのページ分割の割合ならすのに有用かもしれません。(このようにフィルファクタを下げることはページ分割の絶対数を下げるかもしれません。もっとも、この効果はデータベースの処理内容に大きく依存します。) 67.4.2に書かれたB-treeボトムアップインデックス削除技法は余分なタプルのバージョンを保存するのにページの余分な空きに依存しますので、(その効果は通常、重要なものではありませんが)フィルファクタの影響を受けるかもしれません。

In other specific cases it might be useful to increase fillfactor to 100 at <command>CREATE INDEX</command> time as a way of maximizing space utilization. You should only consider this when you are completely sure that the table is static (i.e. that it will never be affected by either inserts or updates). A fillfactor setting of 100 otherwise risks <emphasis>harming</emphasis> performance: even a few updates or inserts will cause a sudden flood of page splits. その他の特別な場合には、空間利用効率を最大にする1つの方法としてCREATE INDEXの時にフィルファクタを100に増やすのが有用かもしれません。 テーブルが静的である(すなわち、挿入や更新により影響を受けない)と完全に確信できる場合にのみ、これを検討すべきです。 そうでなければ、フィルファクタを100に設定することは性能に悪影響を与える危険があります。更新や挿入がたとえ少数であっても、大量のページ分割が突然発生することになるでしょう。

The other index methods use fillfactor in different but roughly analogous ways; the default fillfactor varies between methods. 他のインデックスメソッドでは、フィルファクタを異なる意味で使用しますが、おおよそは同じです。メソッドによってフィルファクタのデフォルト値は異なります。

B-tree indexes additionally accept this parameter: B-treeインデックスはさらに以下のパラメータを受け付けます。

deduplicate_items (boolean) #

Controls usage of the B-tree deduplication technique described in <xref linkend="btree-deduplication"/>. Set to <literal>ON</literal> or <literal>OFF</literal> to enable or disable the optimization. (Alternative spellings of <literal>ON</literal> and <literal>OFF</literal> are allowed as described in <xref linkend="config-setting"/>.) The default is <literal>ON</literal>. 67.4.3に書かれているB-tree重複排除技法の使用を制御します。 最適化を有効、無効にするにはONOFFを設定します。 (20.1に書かれているように、ONOFFの他の綴りも認められています。) デフォルトはONです。

注記

Turning <literal>deduplicate_items</literal> off via <command>ALTER INDEX</command> prevents future insertions from triggering deduplication, but does not in itself make existing posting list tuples use the standard tuple representation. ALTER INDEXdeduplicate_itemsをオフにすると、その後の挿入で重複排除のトリガは発生しなくなりますが、それ自体は既存のポスティングリストタプルが標準のタプル表現を使うようにはしません。

GiST indexes additionally accept this parameter: GiSTインデックスではさらに以下のパラメータを受け付けます。

buffering (enum) #

Determines whether the buffered build technique described in <xref linkend="gist-buffering-build"/> is used to build the index. With <literal>OFF</literal> buffering is disabled, with <literal>ON</literal> it is enabled, and with <literal>AUTO</literal> it is initially disabled, but is turned on on-the-fly once the index size reaches <xref linkend="guc-effective-cache-size"/>. The default is <literal>AUTO</literal>. Note that if sorted build is possible, it will be used instead of buffered build unless <literal>buffering=ON</literal> is specified. 68.4.1で説明するバッファ化構築技術をインデックスを構築する時に使用するかどうかを決定します。 バッファ処理はOFFで無効に、ONで有効になります。 またAUTOと指定すると、最初は無効ですが、インデックスサイズがeffective_cache_sizeに達した後はその場で有効になります。 デフォルトはAUTOです。 ソートしての構築が可能であれば、buffering=ONが指定されていない限りバッファ化構築の代わりに使われることに注意してください。

GIN indexes accept different parameters: GINインデックスでは以下の異なるパラメータを受け付けます。

fastupdate (boolean) #

This setting controls usage of the fast update technique described in <xref linkend="gin-fast-update"/>. It is a Boolean parameter: <literal>ON</literal> enables fast update, <literal>OFF</literal> disables it. The default is <literal>ON</literal>. この設定は70.4.1で説明する高速更新技法を使用するかどうかを制御します。 これは論理値パラメータであり、ONは高速更新を有効に、OFFは無効にします。 デフォルトはONです。

注記

Turning <literal>fastupdate</literal> off via <command>ALTER INDEX</command> prevents future insertions from going into the list of pending index entries, but does not in itself flush previous entries. You might want to <command>VACUUM</command> the table or call <function>gin_clean_pending_list</function> function afterward to ensure the pending list is emptied. ALTER INDEXを使用してfastupdateを無効にすることにより、以後の挿入は待機中のインデックス項目リストに入らないようになります。 しかし、このコマンド自体はこれまでの項目を吐き出しません。 確実に待機中のリストを空にするためには、続いてテーブルをVACUUMするか、gin_clean_pending_list関数を呼び出すのが良いでしょう。

gin_pending_list_limit (integer) #

Custom <xref linkend="guc-gin-pending-list-limit"/> parameter. This value is specified in kilobytes. gin_pending_list_limitのカスタムパラメータです。 値はキロバイト単位で指定します。

<acronym>BRIN</acronym> indexes accept different parameters: BRINインデックスは別のパラメータを受け入れます。

pages_per_range (integer) #

Defines the number of table blocks that make up one block range for each entry of a <acronym>BRIN</acronym> index (see <xref linkend="brin-intro"/> for more details). The default is <literal>128</literal>. BRINインデックスの各エントリについて1つのブロックレンジを構成するテーブルブロックの数を定義します(詳しくは71.1参照)。 デフォルトは128です。

autosummarize (boolean) #

Defines whether a summarization run is queued for the previous page range whenever an insertion is detected on the next one. See <xref linkend="brin-operation"/> for more details. The default is <literal>off</literal>. 次のページへの挿入が検知された時に、いつでも直前のページに対してサマリー処理をキューに入れるかどうかを定義します。 詳細は71.1.1を参照してください。 デフォルトはoffです。

<refsect2 id="sql-createindex-concurrently" xreflabel="Building Indexes Concurrently">

インデックスの同時作成

<title>Building Indexes Concurrently</title>

Creating an index can interfere with regular operation of a database. Normally <productname>PostgreSQL</productname> locks the table to be indexed against writes and performs the entire index build with a single scan of the table. Other transactions can still read the table, but if they try to insert, update, or delete rows in the table they will block until the index build is finished. This could have a severe effect if the system is a live production database. Very large tables can take many hours to be indexed, and even for smaller tables, an index build can lock out writers for periods that are unacceptably long for a production system. インデックスの作成が、通常のデータベース操作に影響を与えることがあります。 通常PostgreSQLは、対象テーブルに対する書き込みをロックしてから、対象テーブル全体のインデックス作成を一度のスキャンで行います。 他のトランザクションはテーブルを読み取ることはできますが、対象テーブル内の行を挿入、更新、削除しようとすると、インデックス作成が完了するまでブロックされます。 実行中の運用状態のデータベースシステムの場合、これは重大な影響を与える可能性があります。 非常に大規模なテーブルに対するインデックス作成は何時間もかかることがあり得ます。 また小規模なテーブルであっても、インデックス作成により、運用状態のシステムとしては受け入れられないほど長い時間、書き込みロックがかかる可能性があります。

<productname>PostgreSQL</productname> supports building indexes without locking out writes. This method is invoked by specifying the <literal>CONCURRENTLY</literal> option of <command>CREATE INDEX</command>. When this option is used, <productname>PostgreSQL</productname> must perform two scans of the table, and in addition it must wait for all existing transactions that could potentially modify or use the index to terminate. Thus this method requires more total work than a standard index build and takes significantly longer to complete. However, since it allows normal operations to continue while the index is built, this method is useful for adding new indexes in a production environment. Of course, the extra CPU and I/O load imposed by the index creation might slow other operations. PostgreSQLは書き込みをロックしないインデックス作成もサポートしています。 CREATE INDEXCONCURRENTLYオプションをつけることでこの方式が行われます。 このオプションを使うと、PostgreSQLはテーブルを2回スキャンしなければなりません。 さらに、潜在的にそのインデックスを更新または使用する可能性がある、実行中のすべてのトランザクションが終わるまで待機しなければなりません。 したがって、この方式は通常の方式よりも総作業時間がかかり、また、完了するまでの時間が非常に長くなります。 しかし、インデックス作成中に通常の操作を行い続けることができますので、この方式は運用環境での新規インデックス作成に有用です。 もちろん、インデックス作成によりCPUや入出力に余分に負荷がかかりますので、他の操作が低速になる可能性があります。

In a concurrent index build, the index is actually entered as an <quote>invalid</quote> index into the system catalogs in one transaction, then two table scans occur in two more transactions. Before each table scan, the index build must wait for existing transactions that have modified the table to terminate. After the second scan, the index build must wait for any transactions that have a snapshot (see <xref linkend="mvcc"/>) predating the second scan to terminate, including transactions used by any phase of concurrent index builds on other tables, if the indexes involved are partial or have columns that are not simple column references. Then finally the index can be marked <quote>valid</quote> and ready for use, and the <command>CREATE INDEX</command> command terminates. Even then, however, the index may not be immediately usable for queries: in the worst case, it cannot be used as long as transactions exist that predate the start of the index build. 同時実行インデックス構築では実際には、1つのトランザクションで無効なインデックスとしてシステムカタログに登録され、さらに2つのトランザクションで2つのテーブルスキャンが起こります。 各テーブルスキャンの前に、インデックス構築はテーブルを修正した実行中のトランザクションが終了するのを待たなければなりません。 2回目のスキャンの後、インデックス構築は2回目のスキャンより前のスナップショット(第13章参照)を持つすべてのトランザクションが終了するのを待たなければなりません。関係するインデックスが部分インデックスであったり、単純な列参照でない列を持っているのなら、ここでのトランザクションは他のテーブルでの同時実行インデックス構築の任意の段階で使われているトランザクションを含みます。 その後でようやく、インデックスは有効であり利用可能であると印が付けられ、CREATE INDEXコマンドが終了します。 しかし、それでもインデックスは問い合わせに対して即座に利用可能であるとは限りません。 最悪の場合、インデックス構築開始前のトランザクションが存在する間は利用できません。

If a problem arises while scanning the table, such as a deadlock or a uniqueness violation in a unique index, the <command>CREATE INDEX</command> command will fail but leave behind an <quote>invalid</quote> index. This index will be ignored for querying purposes because it might be incomplete; however it will still consume update overhead. The <application>psql</application> <command>\d</command> command will report such an index as <literal>INVALID</literal>: たとえばデッドロックや一意性インデックスにおける一意性違反など、テーブルスキャン中に問題が発生すると、CREATE INDEXは失敗しますが、無効なインデックスが残ってしまいます。 こうしたインデックスは完全ではない可能性がありますので、問い合わせの際には無視されます。 しかし、更新時にオーバーヘッドがかかります。 psql\dコマンドでは、こうしたインデックスをINVALIDとして報告します。

postgres=# \d tab
       Table "public.tab"
 Column |  Type   | Collation | Nullable | Default
--------+---------+-----------+----------+---------
 col    | integer |           |          |
Indexes:
    "idx" btree (col) INVALID

The recommended recovery method in such cases is to drop the index and try again to perform <command>CREATE INDEX CONCURRENTLY</command>. (Another possibility is to rebuild the index with <command>REINDEX INDEX CONCURRENTLY</command>). こうした場合の推奨復旧方法は、インデックスを削除し、再度CREATE INDEX CONCURRENTLYを実行することです。 (他にもREINDEX INDEX CONCURRENTLYを使用したインデックスの再作成という方法もあります。)

Another caveat when building a unique index concurrently is that the uniqueness constraint is already being enforced against other transactions when the second table scan begins. This means that constraint violations could be reported in other queries prior to the index becoming available for use, or even in cases where the index build eventually fails. Also, if a failure does occur in the second scan, the <quote>invalid</quote> index continues to enforce its uniqueness constraint afterwards. この他に一意性インデックスを同時作成する場合の注意事項があります。 2回目のテーブルスキャンが始まる時点で、他のトランザクションに対する一意性制約が既に有効になっているという点です。 これは、インデックスが使用できるようになる前やインデックス作成が最終的に失敗したとしても、制約違反が他のトランザクションで報告されてしまうことを意味します。 また、2回目のスキャン中に失敗した後も、無効なインデックスによる一意性制約は強制され続けます。

Concurrent builds of expression indexes and partial indexes are supported. Errors occurring in the evaluation of these expressions could cause behavior similar to that described above for unique constraint violations. 式インデックスや部分インデックスの同時作成もサポートされています。 式の評価中にエラーが発生した場合も、上で説明した一意性制約違反と同様な状況が発生します。

Regular index builds permit other regular index builds on the same table to occur simultaneously, but only one concurrent index build can occur on a table at a time. In either case, schema modification of the table is not allowed while the index is being built. Another difference is that a regular <command>CREATE INDEX</command> command can be performed within a transaction block, but <command>CREATE INDEX CONCURRENTLY</command> cannot. 同一テーブルに対する通常のインデックス作成処理は複数並行して行うことができます。 しかし、あるテーブルに対するインデックスの同時作成は一度に1つしか行うことができません。 また、どちらの場合でもインデックス作成中のテーブルのスキーマ変更はできません。 この他に、通常のCREATE INDEXコマンドはトランザクションブロック内で実行させることができますが、CREATE INDEX CONCURRENTLYは実行させることができないという相違点があります。

Concurrent builds for indexes on partitioned tables are currently not supported. However, you may concurrently build the index on each partition individually and then finally create the partitioned index non-concurrently in order to reduce the time where writes to the partitioned table will be locked out. In this case, building the partitioned index is a metadata only operation. 今の所パーティションテーブルのインデックスの同時作成はサポートされていません。 しかし、パーティションテーブルへの書き込みをロックしている時間を短くするために、各パーティション上のインデックスを個別に同時作成してから最後にパーティションインデックスを非同時的に作成することはできます。 この場合、パーティションインデックスの作成はメタデータのみの操作になります。

注釈

<title>Notes</title>

See <xref linkend="indexes"/> for information about when indexes can be used, when they are not used, and in which particular situations they can be useful. インデックスが、どのような時に使用され、どのような時に使用されないか、また、どのような場合に有用かといった情報については第11章を参照してください。

Currently, only the B-tree, GiST, GIN, and BRIN index methods 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>.) Only B-tree currently supports unique indexes. 現在は、B-tree、GiST、GIN、BRINインデックスメソッドのみが、複数キー列に対するインデックスをサポートしています。 複数キー列があるかどうかはインデックスにINCLUDE列を追加できるかどうかとは独立です。 インデックスはINCLUDE列を含めて32列まで持てます。 (この制限はPostgreSQLのコンパイル時に変更できます。) 現在、B-treeのみが一意性インデックスをサポートしています。

An <firstterm>operator class</firstterm> with optional parameters can be specified for each column of an index. The operator class identifies the operators to be used by the index for that column. For example, a B-tree index on four-byte integers would use the <literal>int4_ops</literal> class; this operator class includes comparison functions for four-byte integers. In practice the default operator class for the column's data type is usually sufficient. The main point of having operator classes is that for some data types, there could be more than one meaningful ordering. For example, we might want to sort a complex-number data type either by absolute value or by real part. We could do this by defining two operator classes for the data type and then selecting the proper class when creating an index. More information about operator classes is in <xref linkend="indexes-opclass"/> and in <xref linkend="xindex"/>. オプションのパラメータのついた演算子クラスは、インデックスのそれぞれの列に指定することができます。 演算子クラスは、その列のインデックスが使う演算子を識別します。 例えば、4バイト整数に対するB-treeインデックスには、int4_opsクラスを使います。 この演算子クラスには、4バイト整数の比較関数が含まれています。 実際の使用では、通常、列のデータ型のデフォルト演算子クラスで十分です。 演算子クラスを保持する主な理由は、データ型の中には有意な順序を2つ以上持つものがあるかもしれないからです。 例えば、複素数のソートで絶対値または実数部のどちらかを使いたい場合がありえます。 これを実現するには、データ型として2つの演算子クラスを定義し、インデックスを作る時に適切なクラスを選択します。 演算子クラスについての詳細は、11.1038.16を参照してください。

When <literal>CREATE INDEX</literal> is invoked on a partitioned table, the default behavior is to recurse to all partitions to ensure they all have matching indexes. Each partition is first checked to determine whether an equivalent index already exists, and if so, that index will become attached as a partition index to the index being created, which will become its parent index. If no matching index exists, a new index will be created and automatically attached; the name of the new index in each partition will be determined as if no index name had been specified in the command. If the <literal>ONLY</literal> option is specified, no recursion is done, and the index is marked invalid. (<command>ALTER INDEX ... ATTACH PARTITION</command> marks the index valid, once all partitions acquire matching indexes.) Note, however, that any partition that is created in the future using <command>CREATE TABLE ... PARTITION OF</command> will automatically have a matching index, regardless of whether <literal>ONLY</literal> is specified. CREATE INDEXがパーティションテーブルに実行されたときのデフォルトの振る舞いは、全パーティションが一致するインデックスを持つようにする全パーティションへの再帰的な実行です。 各パーティションは最初に同等のインデックスが既に存在するかの判断のために検査され、存在するなら作成するインデックスに対するパーティションインデックスとしてアタッチされます。新たに作成するインデックスが既存インデックスの親インデックスとなります。 一致するインデックスが存在しない場合、新たなインデックスが作られて、自動的にアタッチされます。各パーティションの新たなインデックス名は、コマンドでインデックスが指定されなかった場合と同様に決定されます。 ONLYオプションが指定された場合、再帰処理は行われず、そのインデックスは無効と印付けされます。 (ALTER INDEX ... ATTACH PARTITIONは、ひとたび全パーティションが一致するインデックスを得たなら、インデックスを有効に印付けします) しかしながら、ONLYが指定されたとしても、将来にCREATE TABLE ... PARTITION OFを使って作成されるあらゆるパーティションは自動的に一致するインデックスを持つことに注意してください。

For index methods that support ordered scans (currently, only B-tree), the optional clauses <literal>ASC</literal>, <literal>DESC</literal>, <literal>NULLS FIRST</literal>, and/or <literal>NULLS LAST</literal> can be specified to modify the sort ordering of the index. Since an ordered index can be scanned either forward or backward, it is not normally useful to create a single-column <literal>DESC</literal> index &mdash; that sort ordering is already available with a regular index. The value of these options is that multicolumn indexes can be created that match the sort ordering requested by a mixed-ordering query, such as <literal>SELECT ... ORDER BY x ASC, y DESC</literal>. The <literal>NULLS</literal> options are useful if you need to support <quote>nulls sort low</quote> behavior, rather than the default <quote>nulls sort high</quote>, in queries that depend on indexes to avoid sorting steps. 順序付きスキャンをサポートするインデックスメソッド(現時点ではB-Treeのみ)では、ASCDESCNULLS FIRSTNULLS LAST句(省略可能)をオプションで指定し、インデックスのソート順を変更することができます。 順序付きインデックスは正方向にも逆方向にもスキャンすることができますので、単一列に対するDESCインデックスは通常は有用ではありません。 このソート順序はすでに通常のインデックスを使用して実現できます。 これらのオプションの価値は、SELECT ... ORDER BY x ASC, y DESCなどの順序指定が混在する問い合わせによって要求されるソート順に一致する、複数列に対するインデックスを作成できる点です。 NULLSオプションは、インデックスに基づいた問い合わせにおいてソート処理を省略するためにNULLのソート順を低くする動作をサポートする必要がある場合に有用です。 デフォルトの動作はNULLのソート順を高くするです。

The system regularly collects statistics on all of a table's columns. Newly-created non-expression indexes can immediately use these statistics to determine an index's usefulness. For new expression indexes, it is necessary to run <link linkend="sql-analyze"><command>ANALYZE</command></link> or wait for the <link linkend="autovacuum">autovacuum daemon</link> to analyze the table to generate statistics for these indexes. システムは定期的にテーブルの列すべての統計情報を集めています。 新しく作られた、式でないインデックスは、インデックスの有用性を決定するのにその統計情報をすぐに使うことができます。 新しい式インデックスに対しては、そのインデックスのための統計情報を生成するために、ANALYZEを実行するか、autovacuumデーモンがそのテーブルを解析するのを待つことが必要です。

For most index methods, the speed of creating an index is dependent on the setting of <xref linkend="guc-maintenance-work-mem"/>. Larger values will reduce the time needed for index creation, so long as you don't make it larger than the amount of memory really available, which would drive the machine into swapping. ほとんどのインデックスメソッドにおいて、インデックス作成速度はmaintenance_work_memの設定に依存します。 より大きな値を設定すると、インデックス作成に必要となる時間が短縮されます。 ただし、実際に使用できるメモリ量を超えるほど大きくすると、マシンがスワップ状態になり、遅くなります。

<productname>PostgreSQL</productname> can build indexes while leveraging multiple CPUs in order to process the table rows faster. This feature is known as <firstterm>parallel index build</firstterm>. For index methods that support building indexes in parallel (currently, only B-tree), <varname>maintenance_work_mem</varname> specifies the maximum amount of memory that can be used by each index build operation as a whole, regardless of how many worker processes were started. Generally, a cost model automatically determines how many worker processes should be requested, if any. PostgreSQLはテーブルの行をより高速に処理するために複数CPUを効かせてインデックスを作成できます。 この機能はパラレルインデックス作成と呼ばれています。 パラレルでのインデックス作成をサポートしているインデックスメソッド(今のところB-Treeのみ)に対して、maintenance_work_memでは、いくつのワーカープロセスが実行されているかに拘らず、各インデックス作成操作で使うことができる全体のメモリの最大量を指定します。 一般にコストモデルは、もしあるなら、どれだけの数のワーカープロセスを要求すべきかを自動的に決定します。

Parallel index builds may benefit from increasing <varname>maintenance_work_mem</varname> where an equivalent serial index build will see little or no benefit. Note that <varname>maintenance_work_mem</varname> may influence the number of worker processes requested, since parallel workers must have at least a <literal>32MB</literal> share of the total <varname>maintenance_work_mem</varname> budget. There must also be a remaining <literal>32MB</literal> share for the leader process. Increasing <xref linkend="guc-max-parallel-maintenance-workers"/> may allow more workers to be used, which will reduce the time needed for index creation, so long as the index build is not already I/O bound. Of course, there should also be sufficient CPU capacity that would otherwise lie idle. パラレルインデックス作成ではmaintenance_work_memを増やすことで、同様の逐次インデックス作成ではほとんど恩恵がみられない場合でも恩恵があるかもしれません。 パラレルワーカーはmaintenance_work_mem全体の内、少なくとも32MBの割り当て分を持たなければならないため、maintenance_work_memは要求されるワーカープロセス数に影響を及ぼすかもしれないことに注意してください。 また、リーダープロセスに対しても32MBの割り当てを残さなければなりません。 max_parallel_maintenance_workersを増やすことで、より多くのワーカーが使用できるようになるかもしれません。これは、インデックス作成が既にI/Oバウンドであるのでない限り、インデックス作成の所要時間を減らすでしょう。 もちろん、休止している十分なCPU容量もある前提です。

Setting a value for <literal>parallel_workers</literal> via <link linkend="sql-altertable"><command>ALTER TABLE</command></link> directly controls how many parallel worker processes will be requested by a <command>CREATE INDEX</command> against the table. This bypasses the cost model completely, and prevents <varname>maintenance_work_mem</varname> from affecting how many parallel workers are requested. Setting <literal>parallel_workers</literal> to 0 via <command>ALTER TABLE</command> will disable parallel index builds on the table in all cases. ALTER TABLEを通してparallel_workersの値を設定することで、テーブルに対してCREATE INDEXでどれだけのワーカープロセス数が要求されるかを、直接に調整できます。 これはコストモデルを完全に無視して、maintenance_work_memがパラレルワーカーの要求数に影響を与えることを回避します。 ALTER TABLEを通してparallel_workersを0に設定することは、そのテーブルに対するパラレルインデックス作成を全ての場合に無効化します。

ヒント

You might want to reset <literal>parallel_workers</literal> after setting it as part of tuning an index build. This avoids inadvertent changes to query plans, since <literal>parallel_workers</literal> affects <emphasis>all</emphasis> parallel table scans. インデックス作成のチューニング一部としてparallel_workersを設定した後、これをリセットしたいかもしれません。 parallel_workers全てのパラレルテーブルスキャンに影響を与えるので、これは不注意な問い合わせプランの変更を回避します。

While <command>CREATE INDEX</command> with the <literal>CONCURRENTLY</literal> option supports parallel builds without special restrictions, only the first table scan is actually performed in parallel. CONCURRENTLYオプションを伴うCREATE INDEXは特に制限なくパラレル作成をサポートしますが、実際には最初のテーブルスキャンだけがパラレルに実行されます。

Use <link linkend="sql-dropindex"><command>DROP INDEX</command></link> to remove an index. インデックスを削除するには、DROP INDEXを使用してください。

Like any long-running transaction, <command>CREATE INDEX</command> on a table can affect which tuples can be removed by concurrent <command>VACUUM</command> on any other table. 他の時間のかかるトランザクションと同じく、あるテーブルに対するCREATE INDEXは、その他のテーブルに対する同時実行中のVACUUMによりどのタプルが削除できるかに影響します。

Prior releases of <productname>PostgreSQL</productname> also had an R-tree index method. This method has been removed because it had no significant advantages over the GiST method. If <literal>USING rtree</literal> is specified, <command>CREATE INDEX</command> will interpret it as <literal>USING gist</literal>, to simplify conversion of old databases to GiST. 以前のPostgreSQLにはR-treeインデックスメソッドがありました。 GiSTメソッドに比べて大きな利点がありませんでしたので、このメソッドは削除されました。 古いデータベースからGiSTへの変換を簡単にするため、USING rtreeが指定された場合、CREATE INDEXUSING gistと解釈します。

Each backend running <command>CREATE INDEX</command> will report its progress in the <structname>pg_stat_progress_create_index</structname> view. See <xref linkend="create-index-progress-reporting"/> for details. CREATE INDEXを実行している各バックエンドはその進捗をpg_stat_progress_create_indexビューで報告します。 詳細は28.4.4を参照してください。

<title>Examples</title>

To create a unique B-tree index on the column <literal>title</literal> in the table <literal>films</literal>: テーブルfilmsの列titleに一意性のB-treeインデックスを作成します。

CREATE UNIQUE INDEX title_idx ON films (title);

To create a unique B-tree index on the column <literal>title</literal> with included columns <literal>director</literal> and <literal>rating</literal> in the table <literal>films</literal>: テーブルfilmsの列titleに、列directorと列ratingを含めて、一意性のB-treeインデックスを作成します。

CREATE UNIQUE INDEX title_idx ON films (title) INCLUDE (director, rating);

To create a B-Tree index with deduplication disabled: 重複排除を無効にしたB-Treeを作成します。

CREATE INDEX title_idx ON films (title) WITH (deduplicate_items = off);

To create an index on the expression <literal>lower(title)</literal>, allowing efficient case-insensitive searches: 大文字小文字を区別しない検索が効率的になるように、式lower(title)に対してインデックスを作成します。

CREATE INDEX ON films ((lower(title)));

(In this example we have chosen to omit the index name, so the system will choose a name, typically <literal>films_lower_idx</literal>.) (この例では、インデックス名を省略することを選びました。 このためシステムがfilms_lower_idxなどという名前を選ぶことになります。)

To create an index with non-default collation: デフォルト以外の照合順序でインデックスを作成します。

CREATE INDEX title_idx_german ON films (title COLLATE "de_DE");

To create an index with non-default sort ordering of nulls: デフォルトと異なるNULLのソート順を指定したインデックスを作成します。

CREATE INDEX title_idx_nulls_low ON films (title NULLS FIRST);

To create an index with non-default fill factor: デフォルトと異なるフィルファクタを持つインデックスを作成します。

CREATE UNIQUE INDEX title_idx ON films (title) WITH (fillfactor = 70);

To create a <acronym>GIN</acronym> index with fast updates disabled: 高速更新を無効にしてGINインデックスを作成します。

CREATE INDEX gin_idx ON documents_table USING GIN (locations) WITH (fastupdate = off);

To create an index on the column <literal>code</literal> in the table <literal>films</literal> and have the index reside in the tablespace <literal>indexspace</literal>: テーブルfilms上の列codeに対するインデックスを作成します。 また、このインデックスをテーブル空間indexspace内に生成します。

CREATE INDEX code_idx ON films (code) TABLESPACE indexspace;

To create a GiST index on a point attribute so that we can efficiently use box operators on the result of the conversion function: 変換関数の結果に対するbox操作を効率的に使用できるようにpoint属性にGiSTインデックスを作成します。

CREATE INDEX pointloc
    ON points USING gist (box(location,location));
SELECT * FROM points
    WHERE box(location,location) && '(0,0),(1,1)'::box;

To create an index without locking out writes to the table: 対象テーブルへの書き込みをロックせずにインデックスを作成します。

CREATE INDEX CONCURRENTLY sales_quantity_index ON sales_table (quantity);

互換性

<title>Compatibility</title>

<command>CREATE INDEX</command> is a <productname>PostgreSQL</productname> language extension. There are no provisions for indexes in the SQL standard. CREATE INDEXPostgreSQLの拡張です。 標準SQLにはインデックスについての規定はありません。

関連項目

<title>See Also</title> ALTER INDEX, DROP INDEX, REINDEX, 28.4.4