Postgresql

如果不存在則創建索引

  • February 1, 2021

我正在開發一個功能,如果它不存在,我可以添加它。我遇到了無法獲得要比較的索引列表的問題。有什麼想法嗎?

這與使用此程式碼解決的列創建問題類似:

https ://stackoverflow.com/a/12603892/368511

PostgreSQL 中的索引名稱

  • 索引名稱在單個數據庫模式中是唯一的。
  • 索引名稱不能與同一架構中的任何其他索引、(外部)表、(物化)視圖、序列或使用者定義的複合類型相同。
  • 同一架構中的兩個表不能具有相同名稱的索引。(合乎邏輯。)

如果您不關心索引的名稱,請讓 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.5 或更高版本

現在可用:

CREATE INDEX **IF NOT EXISTS** ...

也適用於CREATE INDEX CONCURRENTLY IF NOT EXISTS.

但是,手冊警告

請注意,不能保證現有索引與已創建的索引相同。

這是對對象名稱的簡單檢查。(也適用於下面舊版本的變體。)

要在同一個表上為相同的列查找現有索引:

SELECT pg_get_indexdef(indexrelid)
FROM   pg_index
WHERE  indrelid = 'public.big'::regclass
AND   (indkey::int2[])[:] = ARRAY (
  SELECT attnum
  FROM   unnest('{usr_id, created_at}'::text[]) WITH ORDINALITY i(attname, ord)
  JOIN  (
     SELECT attname, attnum
     FROM   pg_attribute
     WHERE  attrelid = 'public.big'::regclass
     ) a USING (attname)
  ORDER BY ord
  );

限制:

  • 僅適用於列,不適用於其他索引表達式。
  • 還報告部分索引(帶WHERE子句)和覆蓋索引(帶INCLUDE子句)。
  • 報告任何類型的索引,而不僅僅是 B 樹索引。

在繼續之前研究結果(如果有),或根據您的需要細化查詢…

進一步閱讀:

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。看:

這不適用於CREATE INDEX CONCURRENTLY,因為該變體不能包裝在外部事務中。請參閱下面@Gregory 的評論

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
$$;

DO語句是在 Postgres 9.0 中引入的。在早期版本中,您必須創建一個函式來執行相同的操作。手冊中有關的

詳細資訊。 手冊中有關索引的基礎知識。pg_class

引用自:https://dba.stackexchange.com/questions/35616