web-dev-qa-db-ja.com

PostgreSQLは配列列にインデックスを付けることができますか?

ドキュメントでこの質問に対する明確な答えを見つけることができません。列が配列型の場合、入力された値はすべて個別にインデックス付けされますか?

int[]列が1つある単純なテーブルを作成し、それに一意のインデックスを付けました。同じint配列を追加できないことに気付きました。これは、インデックスが各アイテムのインデックスではなく、配列アイテムの複合であると考えるようになります。

INSERT INTO "Test"."Test" VALUES ('{10, 15, 20}');
INSERT INTO "Test"."Test" VALUES ('{10, 20, 30}');

SELECT * FROM "Test"."Test" WHERE 20 = ANY ("Column1");

インデックスはこのクエリを支援していますか?

124
IamIC

はい、配列にインデックスを付けることはできますが、 配列演算子GIN-index type を使用する必要があります。

例:

    CREATE TABLE "Test"("Column1" int[]);
    INSERT INTO "Test" VALUES ('{10, 15, 20}');
    INSERT INTO "Test" VALUES ('{10, 20, 30}');

    CREATE INDEX idx_test on "Test" USING GIN ("Column1");

    -- To enforce index usage because we have only 2 records for this test... 
    SET enable_seqscan TO off;

    EXPLAIN ANALYZE
    SELECT * FROM "Test" WHERE "Column1" @> ARRAY[20];

結果:

Bitmap Heap Scan on "Test"  (cost=4.26..8.27 rows=1 width=32) (actual time=0.014..0.015 rows=2 loops=1)
  Recheck Cond: ("Column1" @> '{20}'::integer[])
  ->  Bitmap Index Scan on idx_test  (cost=0.00..4.26 rows=1 width=0) (actual time=0.009..0.009 rows=2 loops=1)
        Index Cond: ("Column1" @> '{20}'::integer[])
Total runtime: 0.062 ms

多くの場合、gin__int_opsオプションが必要と思われます

create index <index_name> on <table_name> using GIN (<column> gin__int_ops)

Gin__int_opsオプションなしで&&および@>演算子で動作するケースはまだ見ていません

151
Frank Heikens

個々の配列要素にインデックスを付けることが可能になりました。例えば:

CREATE TABLE test (foo int[]);
INSERT INTO test VALUES ('{1,2,3}');
INSERT INTO test VALUES ('{4,5,6}');
CREATE INDEX test_index on test ((foo[1]));
SET enable_seqscan TO off;

EXPLAIN ANALYZE SELECT * from test WHERE foo[1]=1;
                                                QUERY PLAN                                                    
------------------------------------------------------------------------------------------------------------------
 Index Scan using test_index on test  (cost=0.00..8.27 rows=1 width=32) (actual   time=0.070..0.071 rows=1 loops=1)
   Index Cond: (foo[1] = 1)
 Total runtime: 0.112 ms
(3 rows)

これは少なくともPostgres 9.2.1で動作します。配列インデックスごとに個別のインデックスを作成する必要があることに注意してください。この例では、最初の要素のみにインデックスを付けました。

34
Ed4