5

のinformation_schemaとpg_catalogから取得できる情報はたくさんありますpostgresqlpragma index_info(<index_name>)sqlite3で達成するのと同様に、特定のインデックスでインデックス付けされた列に関する情報を取得したいと思います。create indexステートメントを解析せずにこれをどのように達成できますか?

4

2 に答える 2

7

それらのことを見つけるのはとても簡単です。

オプションを指定して psql を実行するだけで、-E使用されている SQL ステートメントが表示されます。したがって、\d index_name を実行すると、次のステートメントが (とりわけ) インデックス列を取得するために使用されます。

SELECT a.attname,
       pg_catalog.format_type (a.atttypid、a.atttypmod)、
       (部分文字列を選択 (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;
于 2011-03-20T21:47:51.017 に答える
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         ""   '
于 2013-05-24T12:52:35.730 に答える