List columns with indexes in PostgreSQL

后端 未结 23 1925
我在风中等你
我在风中等你 2020-11-27 09:14

I would like to get the columns that an index is on in PostgreSQL.

In MySQL you can use SHOW INDEXES FOR table and look at the Column_name

相关标签:
23条回答
  • 2020-11-27 09:32

    Some sample data...

    create table test (a int, b int, c int, constraint pk_test primary key(a, b));
    create table test2 (a int, b int, c int, constraint uk_test2 unique (b, c));
    create table test3 (a int, b int, c int, constraint uk_test3b unique (b), constraint uk_test3c unique (c), constraint uk_test3ab unique (a, b));
    

    Use pg_get_indexdef function:

    select pg_get_indexdef(indexrelid) from pg_index where indrelid = 'test'::regclass;
    
                        pg_get_indexdef
    --------------------------------------------------------
     CREATE UNIQUE INDEX pk_test ON test USING btree (a, b)
    (1 row)
    
    
    select pg_get_indexdef(indexrelid) from pg_index where indrelid = 'test2'::regclass;
                         pg_get_indexdef
    ----------------------------------------------------------
     CREATE UNIQUE INDEX uk_test2 ON test2 USING btree (b, c)
    (1 row)
    
    
    select pg_get_indexdef(indexrelid) from pg_index where indrelid ='test3'::regclass;
                          pg_get_indexdef
    ------------------------------------------------------------
     CREATE UNIQUE INDEX uk_test3b ON test3 USING btree (b)
     CREATE UNIQUE INDEX uk_test3c ON test3 USING btree (c)
     CREATE UNIQUE INDEX uk_test3ab ON test3 USING btree (a, b)
    (3 rows)
    
    0 讨论(0)
  • 2020-11-27 09:32

    Extend to good answer of @Cope360. To get for certain table ( incase their is same table name but different schema ), just using table OID.

    select
         t.relname as table_name
        ,i.relname as index_name
        ,a.attname as column_name
        ,a.attrelid tableid
    
    from
        pg_class t,
        pg_class i,
        pg_index ix,
        pg_attribute a
    where
        t.oid = ix.indrelid
        and i.oid = ix.indexrelid
        and a.attrelid = t.oid
        and a.attnum = ANY(ix.indkey)
        and t.relkind = 'r'
        -- and t.relname like 'tbassettype'
        and a.attrelid = '"dbLegal".tbassettype'::regclass
    order by
        t.relname,
        i.relname;
    

    Explain : I have table name 'tbassettype' in both schema 'dbAsset' and 'dbLegal'. To get only table on dbLegal, just let a.attrelid = its OID.

    0 讨论(0)
  • 2020-11-27 09:34

    PostgreSQL (pg_indexes):

    SELECT * FROM pg_indexes WHERE tablename = 'mytable';
    

    MySQL (SHOW INDEX):

    SHOW INDEX FROM mytable;
    
    0 讨论(0)
  • 2020-11-27 09:34

    Combined with others code and created a view:

    CREATE OR REPLACE VIEW view_index AS 
    SELECT
         n.nspname  as "schema"
        ,t.relname  as "table"
        ,c.relname  as "index"
        ,pg_get_indexdef(indexrelid) as "def"
    FROM pg_catalog.pg_class c
        JOIN pg_catalog.pg_namespace n ON n.oid        = c.relnamespace
        JOIN pg_catalog.pg_index i ON i.indexrelid = c.oid
        JOIN pg_catalog.pg_class t ON i.indrelid   = t.oid
    WHERE c.relkind = 'i'
        and n.nspname not in ('pg_catalog', 'pg_toast')
        and pg_catalog.pg_table_is_visible(c.oid)
    ORDER BY
         n.nspname
        ,t.relname
        ,c.relname;
    
    0 讨论(0)
  • 2020-11-27 09:34

    This commands shows the view of tables variables, indexes and constraints too

    =# \d table_name;
    

    Example:

    testannie=# \d dv.l_customer_account;
    
    0 讨论(0)
  • 2020-11-27 09:34

    I don't think this version exists on this thread yet: it provides both the list of column names along with the ddl for the index.

    CREATE OR REPLACE VIEW V_TABLE_INDEXES AS
    
    SELECT
         n.nspname  as "schema"
        ,t.relname  as "table"
        ,c.relname  as "index"
        ,i.indisunique AS "is_unique"
        ,array_to_string(array_agg(a.attname), ', ') as "columns"
        ,pg_get_indexdef(i.indexrelid) as "ddl"
    FROM pg_catalog.pg_class c
        JOIN pg_catalog.pg_namespace n ON n.oid        = c.relnamespace
        JOIN pg_catalog.pg_index i ON i.indexrelid = c.oid
        JOIN pg_catalog.pg_class t ON i.indrelid   = t.oid
        JOIN pg_attribute a ON a.attrelid = t.oid AND a.attnum = ANY(i.indkey)
    WHERE c.relkind = 'i'
          and n.nspname not in ('pg_catalog', 'pg_toast')
          and pg_catalog.pg_table_is_visible(c.oid)
    GROUP BY
        n.nspname
        ,t.relname
        ,c.relname
        ,i.indisunique
        ,i.indexrelid
    ORDER BY
        n.nspname
        ,t.relname
        ,c.relname;
    

    I found that indexes using functions don't link to column names, so occasionally you find an index listing e.g. one column name when in fact is uses 3.

    Example:

    CREATE INDEX ui1 ON table1 (coalesce(col1,''),coalesce(col2,''),col3)
    

    The query returns only 'col3' as a column on the index, but the DDL shows the full set of columns used in the index.

    0 讨论(0)
提交回复
热议问题