INDEXは、指定したリレーションの指定した列(複数可)に対するインデックスを作ります。リレーションとしてテーブルまたはマテリアライズドビューを取ることができます。(しかし、インデックスの不適切な使用は性能の低下につながる可能性があります)。インデックスのキーフィールドは、列名、または括弧に囲まれた式として指定されます。インデックスメソッドが複数列に対するインデックスをサポートする場合は、複数のフィールドを指定できます。インデックスのフィールドとして、テーブル行の1つ以上の列の値から計算する式を指定できます。この機能は、元のデータに何らかの変換を加えた値を基とするデータへの高速なアクセスを行う手段として使用することができます。'JIM'という句ではインデックスを使用することができます。PostgreSQLはB-tree、ハッシュ、GiST、SP-GiST、GIN、BRINのインデックスメソッドを用意しています。ユーザが独自にインデックスメソッドを定義することもできますが、これはかなり複雑です。WHERE句が存在する場合、部分インデックスが作成されます。部分インデックスは、テーブルの一部、通常は、テーブルの中でよりインデックスが有用な部分のみのエントリを持つインデックスです。請求済みの注文と未請求の注文を情報として持つテーブルがあり、テーブル全体における未請求の注文の割合が小さく、かつ、頻繁に使用される場合、未請求の注文のみにインデックスを作成することで性能を向上できます。部分インデックスのその他の利用方法として、UNIQUE付きのWHEREを使用して、テーブルの部分集合に一意性を強制する例が考えられます。詳細は11.8を参照してください。WHERE句内の式では、元となるテーブルの列のみを参照できます。インデックスを付加する列だけではなく、全ての列を使用することができます。現在、副問い合わせと集約式については、WHEREで使用することができません。同一の制限は、式で表されたインデックスのフィールドにも適用されます。インデックスの定義で使用される全ての関数と演算子は、「不変」(immutable)でなければなりません。結果は入力引数にのみに依存し、(他のテーブルの内容や現時刻などの)外部からの影響を受けてはなりません。この制限によって、インデックスの動作が十分定義されていることが保証されます。インデックス式やWHERE句にユーザ定義の関数を使用する場合、関数を作成する際、IMMUTABLE(不変)オプションを付けることを忘れないでください。パラメータUNIQUEインデックスを(既にデータがある状態で)作成する時、およびテーブルにデータを追加する時に、テーブル内の値が重複していないかを検査します。重複エントリを生じるデータの挿入または更新はエラーとなります。防止するようなロックを獲得せずにインデックスを作成します。通常のインデックス作成処理では、完了するまで対象テーブルへの書き込みはできません(読み取りは可能です)。このオプションを使用する際に注意しなければならない点が複数あります。インデックスの同時作成を参照してください。EXISTS同じ名前のリレーションが既に存在している場合にエラーとしません。この場合、注意が発行されます。既存のインデックスが、作成されようとしていたものと類似のものである保証は全くないことに注意してください。EXISTSを指定する場合はインデックス名が必須です。name作成するインデックスの名前です。この名前には、スキーマ名を含めることはできません。インデックスは、常にその親テーブルと同じスキーマに作成されます。この名前を省略すると、PostgreSQLはその親テーブルの名前とインデックス付けされる列名に基づいた適切な名前を選びます。table_nameインデックスを作成するテーブルの名前です(スキーマ修飾名の場合もあります)。method使用するインデックスメソッドの名前です。btree、hash、gist、spgist、gin、brinから選択します。デフォルトのメソッドはbtreeです。column_nameテーブルの列の名前です。expressionテーブル上の1つ以上の列を使用した式です。通常この式は、構文で示した通り括弧で囲む必要があります。式が関数呼び出し形式になっている場合は括弧を省略することができます。collationインデックスで使用する照合順序の名前です。デフォルトではインデックスはインデックス付け対象の列で宣言された照合順序またはインデックス付け対象の式の結果の照合順序を使用します。デフォルト以外の照合順序を使用する式を含む問い合わせで、デフォルト以外の照合順序を持つインデックスが有用になるかもしれません。opclass演算子クラスの名前です。詳細は下記を参照してください。ASC正方向のソート順を指定します(これがデフォルトです)。DESC逆方向のソート順を指定します。FIRSTNULLを非NULLより前にソートすることを指定します。これはDESCが指定された場合のデフォルトです。LASTNULLを非NULLより後にソートすることを指定します。これはDESCが指定されない場合のデフォルトです。storage_parameterインデックスメソッド固有の格納パラメータの名前です。インデックス格納パラメータを参照してください。tablespace_nameインデックスを生成するテーブル空間です。指定されなかった場合、default_tablespace、もし一時テーブル上のインデックスであれば、temp_tablespacesが考慮されます。predicate部分インデックス用の制約式です。インデックス格納パラメータWITH句を使うと、インデックスの格納パラメータを指定できます。インデックスメソッドはそれぞれ固有の設定可能な格納パラメータを持ちます。B-tree、ハッシュ、GiSTおよびSP-GiSTといったインデックスはすべて次のパラメータを受け付けます。fillfactorインデックス用のフィルファクタは割合(パーセント)で、インデックスメソッドがインデックスページをまとめ上げる時にどの程度ページを使用するかを決定するものです。B-treeでは、リーフページは初期インデックス構築時と右側(新しい最大キー値を追加する方向)にインデックスを拡張する時にこの割合分までページを使用します。その後ページすべてが完全に使用されると分割され、インデックスの効果が徐々に劣化します。B-treeのデフォルトのフィルファクタは90ですが、10から100までの任意の整数値を設定することができます。テーブルが静的な場合、100が最善でインデックスの物理サイズを最小化できます。更新が非常に多い場合は、ページ分割の頻度を少なくするために、より小さなフィルファクタを設定する方が良いです。この他のインデックスメソッドでは、フィルファクタを異なる意味で使用しますが、おおよそは同じです。メソッドによってフィルファクタのデフォルト値は異なります。GiSTインデックスではさらに以下のパラメータを受け付けます。buffering62.4.1で説明するバッファリング構築技術をインデックスを構築する時に使用するかどうかを決定します。OFFで無効に、ONで有効になります。インデックスサイズがeffective_cache_sizeに達した後はその場で有効になります。デフォルトはAUTOです。GINインデックスでは以下の異なるパラメータを受け付けます。fastupdateこの設定は64.4.1で説明する高速更新技法を使用するかどうかを制御します。これは論理値パラメータであり、ONは高速更新を有効に、OFFは無効にします。(19.1の説明のように、ONやOFFと異なる記載も可能です。デフォルトはONです。INDEXを使用してfastupdateを無効にすることにより、以後の挿入は待機中のインデックス項目リストに入らないようになります。このコマンド自体はこれまでの項目を吐き出しません。確実に待機中のリストを空にするためには、続いてテーブルをVACUUMするか、gin_clean_pending_list関数を呼び出すのが良いでしょう。gin_pending_list_limitgin_pending_list_limitのカスタムパラメータです。値はキロバイト単位で指定します。BRINインデックスは別のパラメータを受け入れます。pages_per_rangeBRINインデックスの各エントリについて1つのブロックレンジを構成するテーブルブロックの数を定義します(詳しくは65.1参照)。デフォルトは128です。autosummarize次のページへの挿入が検知された時に、いつでも直前のページに対してサマリー処理を起動するかどうかを定義します。インデックスの同時作成インデックスの作成が、通常のデータベース操作に影響を与えることがあります。通常PostgreSQLは、対象テーブルに対する書き込みをロックしてから、対象テーブル全体のインデックス作成を一度のスキャンで行います。他のトランザクションはテーブルを読み取ることはできますが、対象テーブル内の行を挿入、更新、削除しようとすると、インデックス作成が完了するまでブロックされます。実行中の運用状態のデータベースシステムの場合、これは重大な影響を与える可能性があります。非常に大規模なテーブルに対するインデックス作成は何時間もかかることがあり得ます。小規模なテーブルであっても、インデックス作成により、運用状態のシステムとしては受け入れられないほど長い時間、書き込みロックがかかる可能性があります。PostgreSQLは書き込みをロックしないインデックス作成もサポートしています。INDEXにCONCURRENTLYオプションをつけることでこの方式が行われます。このオプションを使うと、PostgreSQLはテーブルを2回スキャンしなければなりません。潜在的にそのインデックスを更新または使用する可能性がある、実行中のすべてのトランザクションが終わるまで待機しなければなりません。したがって、この方式は通常の方式よりも総作業時間がかかり、また、完了するまでの時間が非常に長くなります。インデックス作成中に通常の操作を行い続けることができますので、この方式は運用環境での新規インデックス作成に有用です。インデックス作成によりCPUや入出力に余分に負荷がかかりますので、他の操作が低速になる可能性があります。同時実行インデックス構築では実際には、1つのトランザクションでシステムカタログに登録され、さらに2つのトランザクションで2つのテーブルスキャンが起こります。各テーブルスキャンの前に、インデックス構築はテーブルを修正した実行中のトランザクションが終了するのを待たなければなりません。2回目のスキャンの後、インデックス構築は2回目のスキャンより前のスナップショット(第13章参照)を持つすべてのトランザクションが終了するのを待たなければなりません。INDEXコマンドが終了します。それでもインデックスは問い合わせに対して即座に利用可能であるとは限りません。最悪の場合、インデックス構築開始前のトランザクションが存在する間は利用できません。INDEXは失敗しますが、「無効な」インデックスが残ってしまいます。したインデックスは完全ではない可能性がありますので、問い合わせの際には無視されます。更新時にオーバーヘッドがかかります。psqlの\dコマンドでは、こうしたインデックスをINVALIDとして報告します。CONCURRENTLYを実行することです。(他にもREINDEXを使用したインデックスの再作成という方法もあります。REINDEXは同時作成をサポートしていませんので、この方法は魅力がありません。)この他に一意性インデックスを同時作成する場合の注意事項があります。2回目のテーブルスキャンが始まる時点で、他のトランザクションに対する一意性制約が既に有効になっているという点です。これは、インデックスが使用できるようになる前やインデックス作成が最終的に失敗したとしても、制約違反が他のトランザクションで報告されてしまうことを意味します。2回目のスキャン中に失敗した後も、「無効な」インデックスによる一意性制約は強制され続けます。式インデックスや部分インデックスの同時作成もサポートされています。式の評価中にエラーが発生した場合も、上で説明した一意性制約違反と同様な状況が発生します。同一テーブルに対する通常のインデックス作成処理は複数並行して行うことができます。あるテーブルに対するインデックスの同時作成は一度に1つしか行うことができません。どの場合でもインデックス作成中はテーブルスキーマの変更はできません。CONCURRENTLYは実行させることができないという相違点があります。注釈インデックスが、どのような時に使用され、どのような時に使用されないか、また、どのような場合に有用かといった情報については第11章を参照してください。現在は、B-tree、GiST、GIN、BRINインデックスメソッドのみが、複数列に対するインデックスをサポートしています。指定できる列は、デフォルトでは32個までです(この制限はPostgreSQLのコンパイル時に変更できます)。現在、B-treeのみが一意性インデックスをサポートしています。演算子クラスは、インデックスのそれぞれの列に指定することができます。演算子クラスは、その列のインデックスが使う演算子を識別します。4バイト整数に対するB-treeインデックスには、int4_opsクラスを使います。この演算子クラスには、4バイト整数の比較関数が含まれています。実際の使用では、通常、列のデータ型のデフォルト演算子クラスで十分です。演算子クラスを保持する主な理由は、データ型の中には有意な順序を2つ以上持つものがあるかもしれないからです。複素数のソートで絶対値または実数部のどちらかを使いたい場合がありえます。これを実現するには、データ型として2つの演算子クラスを定義し、インデックスを作る時に適切なクラスを選択します。演算子クラスについての詳細は、11.9と37.14を参照してください。LAST句(省略可能)をオプションで指定し、インデックスのソート順を変更することができます。順序付きインデックスは正方向にも逆方向にもスキャンすることができますので、単一列に対するDESCインデックスは通常は有用ではありません。このソート順序はすでに通常のインデックスを使用して実現できます。DESCなどの順序指定が混在する問い合わせによって要求されるソート順に一致する、複数列に対するインデックスを作成できる点です。NULLSオプションは、インデックスに基づいた問い合わせにおいてソート処理を省略するために「NULLのソート順を低くする」動作をサポートする必要がある場合に有用です。デフォルトの動作は「NULLのソート順を高くする」です。ほとんどのインデックスメソッドにおいて、インデックス作成速度はmaintenance_work_memの設定に依存します。大きな値を設定すると、インデックス作成に必要となる時間が短縮されます。実際に使用できるメモリ量を超えるほど大きくすると、マシンがスワップ状態になり、遅くなります。INDEXを使用してください。以前のPostgreSQLにはR-treeインデックスメソッドがありました。GiSTメソッドに比べて大きな利点がありませんでしたので、このメソッドは削除されました。gistと解釈します。例テーブルfilmsの列titleにB-treeインデックスを作成します。(title);大文字小文字を区別しない検索が効率的になるように、式lower(title)に対してインデックスを作成します。((lower(title)));(この例では、インデックス名を省略することを選びました。このためシステムがfilms_lower_idxなどという名前を選ぶことになります。)デフォルト以外の照合順序でインデックスを作成します。"de_DE");デフォルトと異なるNULLのソート順を指定したインデックスを作成します。FIRST);デフォルトと異なるフィルファクタを持つインデックスを作成します。70);高速更新を無効にしてGINインデックスを作成します。off);テーブルfilms上の列codeに対するインデックスを作成します。このインデックスをテーブル空間indexspace内に生成します。indexspace;変換関数の結果に対するbox操作を効率的に使用できるようにpoint属性にGiSTインデックスを作成します。'(0,0),(1,1)'::box;対象テーブルへの書き込みをロックせずにインデックスを作成します。INDEXはPostgreSQLの拡張です。標準SQLにはインデックスについての規定はありません。