2011-07-21 194 views
47

查詢獲取列表所有索引名稱,其列名以及postgresql數據庫的表名是什麼?列出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_');` 

回答

84

這將輸出與細節的所有索引(從我的視圖定義中提取):

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)); 
+0

偉大的工作;對我來說,我只需要用戶定義的索引,所以我有另一個條件'WHERE i.relname!〜'^(pg_ | sql _)'' – vchitta

+2

如果你使用我發佈的第二個查詢,你可能不需要這個條件。它去掉任何不在你路徑中的東西(減去系統模式)。 –

40

更人性化的@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 
7

查詢列出數據庫

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; 
+5

這太簡單了。我的變種: 'SELECT schemaname as schema,tablename as table,indexname as index FROM pg_indexes WHERE schemaname ='myschema';' – Chris

+0

怎樣得到未知(可能> 10)個索引的表? –

2

的所有索引如果你也有興趣索引大小,您可以使用此查詢從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; 
1

下面是由

  • 避免嵌套選擇
  • 避免內置功能(也許很難記住)
  • 使用真棒LATERALUNNEST(...) WITH ORDINALITY功能簡化的東西比其他的答案版本可用於後來的Pos​​tgreSQL版本(9.4+)
SELECT 
    tnsp.nspname AS schema_name, 
    trel.relname AS table_name, 
    irel.relname AS index_name, 
    array_agg (a.attname 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) 
JOIN pg_attribute AS a ON trel.oid = a.attrelid AND a.attnum = c.colnum 
GROUP BY tnsp.nspname, trel.relname, irel.relname 
相關問題