web-dev-qa-db-ja.com

インデックスが存在しない場合は作成します

インデックスが存在しない場合にインデックスを追加できるようにする関数に取り組んでいます。比較するインデックスのリストを取得できないという問題が発生しています。何かご意見は?

これは、このコードで解決される列作成の問題と同様の問題です。
https://stackoverflow.com/a/12603892/368511

65
GuidoS

PostgreSQLのインデックス名

  • インデックス名は、単一のデータベーススキーマ全体で一意です。
  • インデックス名は、同じスキーマ内の他のインデックス、(外部)テーブル、(マテリアライズド)ビュー、シーケンス、またはユーザー定義の複合型と同じにすることはできません。
  • 同じスキーマ内の2つのテーブルに同じ名前のインデックスを付けることはできません。 (論理的に従います。)

インデックスの名前を気にしない場合は、Postgresに自動で名前を付けさせます。

_CREATE INDEX ON tbl1 (col1);
_

(ほぼ)同じです:

_CREATE INDEX tbl1_col1_idx ON tbl1 USING btree (col1);
_

Postgresが名前の衝突を避け、自動的に次の空いている名前を選ぶことを除いて:

_tbl1_col1_idx 
tbl1_col1_idx2
tbl1_col1_idx3
...
_

やってみなよ。しかし、明らかに、複数の冗長なインデックスを作成したくないでしょう。だから、盲目的に新しいものを作成するのは良い考えではありません。

存在をテストする

Postgres 9.3以前

テストする非常に簡単な方法は、スキーマ修飾名を regclass にキャストすることです。

_SELECT 'myschema.myname'::regclass;
_

例外をスローする場合、名前は自由です。
または DO ステートメントで使用される、例外をスローせずに同じものをテストするには:

_DO
$$
BEGIN
   IF NOT EXISTS (
      SELECT
      FROM   pg_class c
      JOIN   pg_namespace n ON n.oid = c.relnamespace
      WHERE  c.relname = 'mytable_mycolumn_idx'
      AND    n.nspname = 'myschema'
   ) THEN

        CREATE INDEX mytable_mycolumn_idx ON myschema.mytable (mycolumn);
    END IF;
END
$$;
_

これは_CREATE INDEX CONCURRENTLY_では機能しません。そのバリアントは外部トランザクションでラップできないためです。以下の @ Gregoryによるコメント を参照してください。

DO ステートメントはPostgres 9.0で導入されました。以前のバージョンでは、同じことを行うために function を作成する必要があります。
_pg_class_の詳細
マニュアルの索引 に関する基本事項。

Postgres 9.4

新しい関数to_regclass()を使用して、例外をスローせずにチェックできます。

_DO
$$
BEGIN
   IF to_regclass('myschema.mytable_mycolumn_idx') IS NULL THEN
      CREATE INDEX mytable_mycolumn_idx ON myschema.mytable (mycolumn);
   END IF;

END
$$;
_

その名前のインデックス(または別のオブジェクト)が存在しない場合は、NULLを返します。見る:

Postgres 9.5

利用可能になりました:

_CREATE INDEX IF NOT EXISTS ..._

Thatは_CREATE INDEX CONCURRENTLY IF NOT EXISTS_でも機能します。

ただし、 マニュアルで警告

既存のインデックスが、作成されたものと同じであるという保証はありません。

これは、オブジェクト名の単純なチェックです。ここのすべてのバリアントに適用されます。

105

9.5で利用できるようになります。これが実際のgit commitです https://github.com/postgres/postgres/commit/08309aaf74ee879699165ec8a2d53e56f2d2e947

Pgハッカーに関するディスカッション http://postgresql.nabble.com/CREATE-IF-NOT-EXISTS-INDEX-td5821173.html

12
Sergey Mirvoda