List columns with indexes in PostgreSQL

后端 未结 23 1928
我在风中等你
我在风中等你 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:40

    \d table_name shows this information from psql, but if you want to get such information from database using SQL then have a look at Extracting META information from PostgreSQL.

    I use such info in my utility to report some info from db schema to compare PostgreSQL databases in test and production environments.

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

    @cope360 's excellent answer, converted to use join syntax.

    select t.relname as table_name
         , i.relname as index_name
         , array_to_string(array_agg(a.attname), ', ') as column_names
    from pg_class t
    join pg_index ix
    on t.oid = ix.indrelid
    join pg_class i
    on i.oid = ix.indexrelid
    join pg_attribute a
    on a.attrelid = t.oid
    and a.attnum = ANY(ix.indkey)
    where t.relkind = 'r'
    and t.relname like 'test%'
    group by t.relname
           , i.relname
    order by t.relname
           , i.relname
    ;
    
    0 讨论(0)
  • 2020-11-27 09:42

    Please try the query below to drill down to required index's

    Query as below -- i have tried this personally and use it frequently.

    SELECT n.nspname as "Schema",
      c.relname as "Name",
      CASE c.relkind WHEN 'r' THEN 'table' WHEN 'v' THEN 'view' WHEN 'i' 
    THEN 'index' WHEN 'S' THEN 'sequence' WHEN 's' THEN 'special' END as "Type",
      u.usename as "Owner",
     c2.relname as "Table"
    FROM pg_catalog.pg_class c
         JOIN pg_catalog.pg_index i ON i.indexrelid = c.oid
         JOIN pg_catalog.pg_class c2 ON i.indrelid = c2.oid
         LEFT JOIN pg_catalog.pg_user u ON u.usesysid = c.relowner
         LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
    WHERE c.relkind IN ('i','')
          AND n.nspname NOT IN ('pg_catalog', 'pg_toast')
          AND pg_catalog.pg_table_is_visible(c.oid)
          AND c2.relname like '%agg_transaction%' --table name
          AND nspname = 'edjus' -- schema name 
    ORDER BY 1,2;
    
    0 讨论(0)
  • 2020-11-27 09:42

    How about a simple solution:

    SELECT 
      t.relname table_name,
      ix.relname index_name,
      indisunique,
      indisprimary, 
      regexp_replace(pg_get_indexdef(indexrelid), '.*\((.*)\)', '\1') columns
    FROM pg_index i
    JOIN pg_class t ON t.oid = i.indrelid
    JOIN pg_class ix ON ix.oid = i.indexrelid
    WHERE t.relname LIKE 'test%'
    

    `

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

    The accepted answer by @cope360 is good, but I wanted something a little more like Oracle's DBA_IND_COLUMNS, ALL_IND_COLUMNS, and USER_IND_COLUMNS (e.g., reports the table/index schema and the position of the index in a multicolumn index), so I adapted the accepted answer into this:

    with
     ind_cols as (
    select
        n.nspname as schema_name,
        t.relname as table_name,
        i.relname as index_name,
        a.attname as column_name,
        1 + array_position(ix.indkey, a.attnum) as column_position
    from
         pg_catalog.pg_class t
    join pg_catalog.pg_attribute a on t.oid    =      a.attrelid 
    join pg_catalog.pg_index ix    on t.oid    =     ix.indrelid
    join pg_catalog.pg_class i     on a.attnum = any(ix.indkey)
                                  and i.oid    =     ix.indexrelid
    join pg_catalog.pg_namespace n on n.oid    =      t.relnamespace
    where t.relkind = 'r'
    order by
        t.relname,
        i.relname,
        array_position(ix.indkey, a.attnum)
    )
    select * 
    from ind_cols
    where schema_name = 'test'
      and table_name  = 'indextest'
    order by schema_name, table_name
    ;
    

    This gives an output like:

     schema_name | table_name | index_name | column_name | column_position 
    -------------+------------+------------+-------------+-----------------
     test        | indextest  | testind1   | singleindex |               1
     test        | indextest  | testind2   | firstoftwo  |               1
     test        | indextest  | testind2   | secondoftwo |               2
    (3 rows)
    
    0 讨论(0)
  • 2020-11-27 09:50
    select t.relname as table_name, 
           i.relname as index_name, 
           array_position(ix.indkey,a.attnum) pos, 
           a.attname as column_name
    from pg_class t
    join pg_index ix on t.oid = ix.indrelid
    join pg_class i on i.oid = ix.indexrelid
    join pg_attribute a on a.attrelid = t.oid and a.attnum = ANY(ix.indkey)
    where t.relkind = 'r'
    and t.relname like 'orders'
    order by t.relname, i.relname, array_position(ix.indkey,a.attnum)
    
    0 讨论(0)
提交回复
热议问题