존재하지 않는 인덱스 생성


60

색인이 존재하지 않으면 색인을 추가 할 수있는 기능을 개발 중입니다. 비교할 인덱스 목록을 얻을 수없는 문제가 발생했습니다. 이견있는 사람?

이것은이 코드로 해결 된 열 생성 문제와 비슷한 문제입니다.
https://stackoverflow.com/a/12603892/368511


다음을 시도해보십시오. SELECT * from pg_indexes 여기서 schemaname = '[schemaname]'및 indexname = '[indexname]'. [schemaname] 및 [indexname]을 적절한 값으로 바꾸십시오. 참조 : postgresql.org/docs/9.1/static/view-pg-indexes.html
jbarrameda

답변:


102

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.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에서 도입되었습니다. 이전 버전에서는 동일한 기능 을 수행해야합니다. 매뉴얼
에 대한 자세한 내용 . 설명서의 색인에 대한 기본 사항 .pg_class

포스트그레스 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을 반환합니다. 보다:

포스트그레스 9.5

사용 가능 :

CREATE INDEX IF NOT EXISTS ...

그것은 또한 작동합니다 CREATE INDEX CONCURRENTLY IF NOT EXISTS.

그러나 매뉴얼은 다음 과 같이 경고합니다 .

기존 색인이 작성된 색인과 다름을 보증하지 않습니다.

객체 이름을 확인합니다. 여기의 모든 변형에 적용됩니다.


7
좋은 대답을하면서이 CONCURRENTLY방법으로 인덱스를 추가 할 수는 없습니다 . 당신은 얻을 것이다 ERROR: CREATE INDEX CONCURRENTLY cannot be executed from a function or multi-command string.
gregoltsov

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.