Search code examples
arrayspostgresqlindexingoperators

Can PostgreSQL index array columns?


I can't find a definite answer to this question in the documentation. If a column is an array type, will all the entered values be individually indexed?

I created a simple table with one int[] column, and put a unique index on it. I noticed that I couldn't add the same array of ints, which leads me to believe the index is a composite of the array items, not an index of each item.

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

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

Is the index helping this query?


Solution

  • Yes you can index an array, but you have to use the array operators and the GIN-index type.

    Example:

        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" gin__int_ops);
                
        EXPLAIN ANALYZE
        SELECT * FROM "Test" WHERE "Column1" @> ARRAY[20];
    

    Result:

    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
    

    Note

    it appears that in many cases the gin__int_ops option is required

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

    I have not yet seen a case where it would work with the && and @> operator without the gin__int_ops options