【问题标题】:List all index names, column names and its table name of a PostgreSQL database列出一个PostgreSQL数据库的所有索引名、列名及其表名
【发布时间】:2011-10-10 06:50:33
【问题描述】:

获取postgresql数据库的所有索引名、列名和表名的查询是什么?

我曾尝试使用此查询获取数据库中所有索引的列表,但如何获取索引列表、其列名和表名?

 SELECT *
 FROM pg_class, pg_index
 WHERE pg_class.oid = pg_index.indexrelid
 AND pg_class.oid IN (
     SELECT indexrelid
     FROM pg_index, pg_class
     WHERE pg_class.oid=pg_index.indrelid
     AND indisunique != 't'
     AND indisprimary != 't'
     AND relname !~ '^pg_');

【问题讨论】:

    标签: postgresql


    【解决方案1】:

    对于非复合索引

    select  t.relname,i.relname ,
         STRING_AGG(pga.attname||'', ','order by i.relname,pga.attnum)   as columnName          
        from pg_class t inner join pg_index ix
                  on t.oid = ix.indrelid
                  inner join  pg_class i
                  on i.oid = ix.indexrelid
                   inner join  pg_attribute pga
                  on
                   pga.attrelid = i.oid 
                inner join pg_indexes pgidx
                    on pgidx.indexname=i.relname
                 where 
                   t.relkind = 'r' 
                and pgidx.schemaname='asit_cm'
                 and t.relname ='accessory'
                 group by  t.relname,i.relname having count(*)=1
    

    对于复合索引

    select  t.relname,i.relname ,
         STRING_AGG(pga.attname||'', ','order by i.relname,pga.attnum)   as columnName          
        from pg_class t inner join pg_index ix
                  on t.oid = ix.indrelid
                  inner join  pg_class i
                  on i.oid = ix.indexrelid
                   inner join  pg_attribute pga
                  on
                   pga.attrelid = i.oid 
                inner join pg_indexes pgidx
                    on pgidx.indexname=i.relname
                 where 
                   t.relkind = 'r' 
                and pgidx.schemaname='asit_cm'
                 and t.relname ='accessory'
                 group by  t.relname,i.relname having count(*)=1
    

    【讨论】:

      【解决方案2】:

      与其他答案相比,这是一个简化了事情的版本

      • 避免嵌套选择
      • 避免使用内置函数(可能很难记住)
      • 使用 PostgreSQL 更高版本 (9.4+) 中提供的 LATERALUNNEST(...) WITH ORDINALITY 功能
      SELECT
        tnsp.nspname AS schema_name,
        trel.relname AS table_name,
        irel.relname AS index_name,
        array_agg (
           a.attname 
        || ' ' || CASE o.option & 1 WHEN 1 THEN 'DESC' ELSE 'ASC' END
        || ' ' || CASE o.option & 2 WHEN 2 THEN 'NULLS FIRST' ELSE 'NULLS LAST' END
          ORDER BY c.ordinality
        ) AS columns
      FROM pg_index AS i
      JOIN pg_class AS trel ON trel.oid = i.indrelid
      JOIN pg_namespace AS tnsp ON trel.relnamespace = tnsp.oid
      JOIN pg_class AS irel ON irel.oid = i.indexrelid
      CROSS JOIN LATERAL unnest (i.indkey) WITH ORDINALITY AS c (colnum, ordinality)
      LEFT JOIN LATERAL unnest (i.indoption) WITH ORDINALITY AS o (option, ordinality)
        ON c.ordinality = o.ordinality
      JOIN pg_attribute AS a ON trel.oid = a.attrelid AND a.attnum = c.colnum
      GROUP BY tnsp.nspname, trel.relname, irel.relname
      

      【讨论】:

      • 这个解决方案也不错。问题是:在“列”中,当索引下降时,没有显示“DESC”。有谁知道,我在哪里可以找到显示字段下降的那个位?
      • @Jettero:更新了查询以同时显示ASC / DESCNULLS FIRST / NULLS LAST
      • 我确实放了两个字段,以获得索引的完整信息:“,i.indisunique,i.indisprimary,”
      • 这不包括列中的表达式
      【解决方案3】:

      如果您也对索引大小感兴趣,您可以使用来自PostgreSQL Wiki 的查询。

      SELECT
          t.tablename,
          indexname,
          c.reltuples AS num_rows,
          pg_size_pretty(pg_relation_size(quote_ident(t.tablename)::text)) AS table_size,
          pg_size_pretty(pg_relation_size(quote_ident(indexrelname)::text)) AS index_size,
          CASE WHEN indisunique THEN 'Y'
             ELSE 'N'
          END AS UNIQUE,
          idx_scan AS number_of_scans,
          idx_tup_read AS tuples_read,
          idx_tup_fetch AS tuples_fetched
      FROM pg_tables t
      LEFT OUTER JOIN pg_class c ON t.tablename=c.relname
      LEFT OUTER JOIN
          ( SELECT c.relname AS ctablename, ipg.relname AS indexname, x.indnatts AS number_of_columns, idx_scan, idx_tup_read, idx_tup_fetch, indexrelname, indisunique FROM pg_index x
                 JOIN pg_class c ON c.oid = x.indrelid
                 JOIN pg_class ipg ON ipg.oid = x.indexrelid
                 JOIN pg_stat_all_indexes psai ON x.indexrelid = psai.indexrelid )
          AS foo
          ON t.tablename = foo.ctablename
      WHERE t.schemaname='public'
      ORDER BY 1,2;
      

      【讨论】:

        【解决方案4】:

        @Denis 解决方案更人性化的版本:

        SELECT
          U.usename                AS user_name,
          ns.nspname               AS schema_name,
          idx.indrelid :: REGCLASS AS table_name,
          i.relname                AS index_name,
          idx.indisunique          AS is_unique,
          idx.indisprimary         AS is_primary,
          am.amname                AS index_type,
          idx.indkey,
               ARRAY(
                   SELECT pg_get_indexdef(idx.indexrelid, k + 1, TRUE)
                   FROM
                     generate_subscripts(idx.indkey, 1) AS k
                   ORDER BY k
               ) AS index_keys,
          (idx.indexprs IS NOT NULL) OR (idx.indkey::int[] @> array[0]) AS is_functional,
          idx.indpred IS NOT NULL AS is_partial
        FROM pg_index AS idx
          JOIN pg_class AS i
            ON i.oid = idx.indexrelid
          JOIN pg_am AS am
            ON i.relam = am.oid
          JOIN pg_namespace AS NS ON i.relnamespace = NS.OID
          JOIN pg_user AS U ON i.relowner = U.usesysid
        WHERE NOT nspname LIKE 'pg%'; -- Excluding system tables
        

        【讨论】:

        • 解决方案很好。问题是:在“index_keys”中,当索引下降时没有显示“DESC”。有谁知道,我在哪里可以找到显示字段下降的那个位?
        【解决方案5】:

        列出数据库所有索引的查询

        SELECT
          tablename,
          indexes [1],
          indexes [2],
          indexes [3],
          indexes [4],
          indexes [5],
          indexes [6],
          indexes [7],
          indexes [8],
          indexes [9],
          indexes [10]
        FROM (SELECT
          tablename,
          array_agg(indexname) AS indexes
        FROM pg_indexes
        WHERE schemaname = 'public'
        GROUP BY tablename) as sub;
        

        【讨论】:

        • 这要简单得多。我的变化:SELECT schemaname as schema, tablename as table, indexname as index FROM pg_indexes WHERE schemaname='myschema';
        • 索引数未知(可能 >10)的表怎么办?
        【解决方案6】:

        这将输出所有索引的详细信息(从我的视图定义中提取):

        SELECT i.relname as indname,
               i.relowner as indowner,
               idx.indrelid::regclass,
               am.amname as indam,
               idx.indkey,
               ARRAY(
               SELECT pg_get_indexdef(idx.indexrelid, k + 1, true)
               FROM generate_subscripts(idx.indkey, 1) as k
               ORDER BY k
               ) as indkey_names,
               idx.indexprs IS NOT NULL as indexprs,
               idx.indpred IS NOT NULL as indpred
        FROM   pg_index as idx
        JOIN   pg_class as i
        ON     i.oid = idx.indexrelid
        JOIN   pg_am as am
        ON     i.relam = am.oid;
        

        可以选择在末尾添加一个额外的连接以修剪命名空间:

        SELECT i.relname as indname,
               i.relowner as indowner,
               idx.indrelid::regclass,
               am.amname as indam,
               idx.indkey,
               ARRAY(
               SELECT pg_get_indexdef(idx.indexrelid, k + 1, true)
               FROM generate_subscripts(idx.indkey, 1) as k
               ORDER BY k
               ) as indkey_names,
               idx.indexprs IS NOT NULL as indexprs,
               idx.indpred IS NOT NULL as indpred
        FROM   pg_index as idx
        JOIN   pg_class as i
        ON     i.oid = idx.indexrelid
        JOIN   pg_am as am
        ON     i.relam = am.oid
        JOIN   pg_namespace as ns
        ON     ns.oid = i.relnamespace
        AND    ns.nspname = ANY(current_schemas(false));
        

        【讨论】:

        • 很好用;对我来说,我只需要用户定义的索引,所以我有另一个条件WHERE i.relname !~ '^(pg_|sql_)'
        • 如果您使用我发布的第二个查询,您可能不需要该条件。它会剔除任何不在您的路径中的东西(减去系统模式)。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-08-22
        • 1970-01-01
        • 2023-03-26
        • 2017-12-23
        • 2012-08-16
        • 2020-10-02
        • 2019-06-03
        相关资源
        最近更新 更多