2011-03-20 43 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   "" '