2011-03-20 71 views
5

有大量的信息,可以從0123x的information_schema和pg_catalog檢索。我想檢索由某個索引索引的列的信息,類似於我在sqlite3中使用pragma index_info(<index_name>)獲得的信息。如何在不解析create index聲明的情況下實現?postgresql:如何列表索引列?

+0

@OMG小馬:因爲答案並不像聽起來那麼簡單。 – intgr 2011-03-20 21:43:10

回答

7

這些東西很容易找到。

只需使用-E選項運行psql,它將向您顯示所使用的SQL語句。所以運行\ d INDEX_NAME下面的語句(等等)時,用於檢索索引中的列:

 
SELECT a.attname, 
     pg_catalog.format_type (a.atttypid,a.atttypmod), 
     (SELECT SUBSTRING (pg_catalog.pg_get_expr (d.adbin,d.adrelid) FOR 128) 
     FROM pg_catalog.pg_attrdef d 
     WHERE d.adrelid = a.attrelid 
     AND d.adnum = a.attnum 
     AND a.atthasdef)a.attnotnull, 
     a.attnum, 
     pg_catalog.pg_get_indexdef (a.attrelid,a.attnum,TRUE) AS indexdef 
FROM pg_catalog.pg_attribute a 
WHERE a.attrelid = (SELECT oid FROM pg_class WHERE relname = 'index_name') 
AND a.attnum > 0 
AND NOT a.attisdropped 
ORDER BY a.attnum; 
+0

我不知道,你可以用'\ d'顯示索引信息。這是非常有用的,以及'-E'選項。非常感謝。 – gruszczy 2011-03-20 22:04:02

0

接受的答案並沒有爲我工作(在執行時發生錯誤)。

無論如何,你可以列出數據庫中的所有列和標記所有索引以某種方式列 (能力限制結果行集被提及作爲註釋):

WITH 
    table_select as (
     select row_number() over(ORDER BY relname) as rownum, 
     c.relname, c.oid, c.reltuples 
     FROM pg_class c 
     JOIN pg_namespace n ON (n.oid = c.relnamespace) 
     WHERE c.relkind = 'r'::"char" 
       --AND n.nspname = '%MyNameSpaceHere%' 
     ORDER BY c.relname  
    ), 
    indxs as (
    select distinct t.relname as table_name, a.attname as column_name 
    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 'mytable here' 
     and cast (i.oid::regclass as text) like '%MyNameSpaceHere%' 
    order by 
     t.relname --, i.relname 
    ), 
    cols as (
    select a.attname, a.attrelid, c.oid, col.TABLE_NAME, col.COLUMN_NAME 
     FROM table_select c 
     JOIN pg_attribute a ON (a.attrelid = c.oid) AND (a.attname <> 'tableoid') 
     LEFT JOIN information_schema.columns col ON 
(col.TABLE_NAME = c.relname AND col.COLUMN_NAME = a.attname) 
     WHERE  
      (a.attnum >= 0) --attnum > 0 for real columns 
    ) 

    --select * from table_select t 
    select c.TABLE_NAME, c.COLUMN_NAME, 
     case when i.column_name is not null then 'Y' else '' end as is_indexed 
    from cols c 
    left join indxs i on (i.table_name = c.table_name and i.column_name = c.column_name) 

的例子結果:

table_name column_name is_indexed 
    'events  id   "Y" 
    events  type   "Y" 
    events  descr   "" '