postgresql:如何列出索引列?

发布于 2024-10-24 07:26:28 字数 212 浏览 4 评论 0原文

有很多信息可以从 postgresql 中的 information_schema 和 pg_catalog 中检索。我想检索有关由某个索引索引的列的信息,类似于我在 sqlite3 中使用 pragma index_info() 实现的效果。在不解析 create index 语句的情况下如何实现这一点?

There is a lot of information, that can be retrieved from information_schema and pg_catalog in postgresql. I would like to retrieve information about columns indexed by a certain index, similar to what I would achieve with pragma index_info(<index_name>) in sqlite3. How can this be achieved without parsing create index statement?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

慢慢从新开始 2024-10-31 07:26:28

这些事情很容易找到。

只需使用 -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;

Those things are pretty easy to find out.

Simply run psql with the -E option and it will show you the SQL statements that are used. So when running \d index_name the following statement (among others) is used to retrieve the index columns:

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;
め可乐爱微笑 2024-10-31 07:26:28

接受的答案对我不起作用(执行时发生错误)。

无论如何,您可以列出数据库中的所有列并以某种方式标记所有索引列
(限制结果行集的能力作为注释提到):

    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         ""   '

Accepted answer didn't work for me (error occured on execution).

Anyway, you can list all columns in the database and mark all indexed in some way columns
(abilities to limit result rowset are mentioned as comments):

    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)

The example result:

    table_name column_name is_indexed
   'events        id          "Y"
    events       type         "Y"
    events       descr         ""   '
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文