在 PostgreSQL 中列出具有索引的列
Posted
技术标签:
【中文标题】在 PostgreSQL 中列出具有索引的列【英文标题】:List columns with indexes in PostgreSQL 【发布时间】:2011-01-13 07:51:44 【问题描述】:我想在 PostgreSQL 中获取索引所在的列。
在 mysql 中,您可以使用 SHOW INDEXES FOR table
并查看 Column_name
列。
mysql> show indexes from foos;
+-------+------------+---------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+-------+------------+---------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| foos | 0 | PRIMARY | 1 | id | A | 19710 | NULL | NULL | | BTREE | |
| foos | 0 | index_foos_on_email | 1 | email | A | 19710 | NULL | NULL | YES | BTREE | |
| foos | 1 | index_foos_on_name | 1 | name | A | 19710 | NULL | NULL | | BTREE | |
+-------+------------+---------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
PostgreSQL 有类似的东西吗?
我在psql
命令提示符下尝试了\d
(使用-E
选项来显示SQL),但它没有显示我正在寻找的信息。
更新:感谢所有添加答案的人。 cope360 给了我我想要的东西,但是有几个人附和了非常有用的链接。为了将来参考,请查看pg_index(通过Milen A. Radev)的文档和非常有用的文章Extracting META information from PostgreSQL(通过Michał Niklas)。
【问题讨论】:
澄清一下:您希望您的程序能够在运行时确定哪些列被索引,对吧?与你相反的编程知识。 是的,正确的。理想情况下,我想要一个仅列出索引所在列的 SQL 语句。但我知道 PostgreSQL 比 MySQL 更复杂,索引可能在函数上,等等。 【参考方案1】:也许您想获取实际的 CREATE INDEX
语句,以便您可以删除它们并稍后重新创建(这是我的情况)作为管理过程的一部分。在这种情况下,您可以使用pg_dump
仅转储post-data
部分,然后将grep 'CREATE INDEX'
转出。
PGPASSWORD=<pwd> pg_dump --host <host> --port <port> -U <user> -d <database> --section=post-data > post-data.sql
grep 'CREATE INDEX' postdata.sql > create_index.sql
这可能会有所帮助,因为某些索引可能难以重新创建,例如使用特定 opclass 的索引(例如 gin_trgm_ops
)或其他
我通常很难重建。
【讨论】:
【参考方案2】:# \di
简单快捷的方法是\di
,它将列出当前数据库中的所有索引。
$ \di
List of relations
Schema | Name | Type | Owner | Table
--------+-----------------------------+-------+----------+---------------
public | part_delivery_index | index | shipper | part_delivery
public | part_delivery_pkey | index | shipper | part_delivery
public | shipment_by_mandator | index | shipper | shipment_info
public | shipment_by_number_and_size | index | shipper | shipment_info
public | shipment_info_pkey | index | shipper | shipment_info
(5 rows)
\di
是\d
命令的“小弟”,它将列出当前d数据库的所有关系。因此\di
当然代表“给我看这个d数据库i索引”。
键入 \diS
将列出系统范围内使用的所有索引,这意味着您也可以获得所有 pg_catalog 索引。
$ \diS
List of relations
Schema | Name | Type | Owner | Table
------------+-------------------------------------------+-------+----------+-------------------------
pg_catalog | pg_aggregate_fnoid_index | index | postgres | pg_aggregate
pg_catalog | pg_am_name_index | index | postgres | pg_am
pg_catalog | pg_am_oid_index | index | postgres | pg_am
pg_catalog | pg_amop_fam_strat_index | index | postgres | pg_amop
pg_catalog | pg_amop_oid_index | index | postgres | pg_amop
pg_catalog | pg_amop_opr_fam_index | index | postgres | pg_amop
pg_catalog | pg_amproc_fam_proc_index | index | postgres | pg_amproc
pg_catalog | pg_amproc_oid_index | index | postgres | pg_amproc
pg_catalog | pg_attrdef_adrelid_adnum_index | index | postgres | pg_attrdef
--More--
使用这两个命令,您可以在其后添加+
以获得更多信息,例如大小 - 磁盘空间 - 索引需求和描述(如果有)。
$ \di+
List of relations
Schema | Name | Type | Owner | Table | Size | Description
--------+-----------------------------+-------+----------+---------------+-------+-------------
public | part_delivery_index | index | shipper | part_delivery | 16 kB |
public | part_delivery_pkey | index | shipper | part_delivery | 16 kB |
public | shipment_by_mandator | index | shipper | shipment_info | 19 MB |
public | shipment_by_number_and_size | index | shipper | shipment_info | 19 MB |
public | shipment_info_pkey | index | shipper | shipment_info | 53 MB |
(5 rows)
在 psql 中,您可以轻松找到有关键入 \?
的命令的帮助。
【讨论】:
但它不显示创建索引的列名。复合主键索引有很多列,这些列是看不到的。【参考方案3】:@cope360 的The accepted answer 很好,但我想要一些更像 Oracle 的 DBA_IND_COLUMNS、ALL_IND_COLUMNS 和 USER_IND_COLUMNS 的东西(例如,报告表/索引架构和索引在多列索引中的位置),所以我将接受的答案改编为:
with
ind_cols as (
select
n.nspname as schema_name,
t.relname as table_name,
i.relname as index_name,
a.attname as column_name,
1 + array_position(ix.indkey, a.attnum) as column_position
from
pg_catalog.pg_class t
join pg_catalog.pg_attribute a on t.oid = a.attrelid
join pg_catalog.pg_index ix on t.oid = ix.indrelid
join pg_catalog.pg_class i on a.attnum = any(ix.indkey)
and i.oid = ix.indexrelid
join pg_catalog.pg_namespace n on n.oid = t.relnamespace
where t.relkind = 'r'
order by
t.relname,
i.relname,
array_position(ix.indkey, a.attnum)
)
select *
from ind_cols
where schema_name = 'test'
and table_name = 'indextest'
order by schema_name, table_name
;
这会给出如下输出:
schema_name | table_name | index_name | column_name | column_position
-------------+------------+------------+-------------+-----------------
test | indextest | testind1 | singleindex | 1
test | indextest | testind2 | firstoftwo | 1
test | indextest | testind2 | secondoftwo | 2
(3 rows)
【讨论】:
【参考方案4】:select t.relname as table_name,
i.relname as index_name,
array_position(ix.indkey,a.attnum) pos,
a.attname as column_name
from pg_class t
join pg_index ix on t.oid = ix.indrelid
join pg_class i on i.oid = ix.indexrelid
join pg_attribute a on a.attrelid = t.oid and a.attnum = ANY(ix.indkey)
where t.relkind = 'r'
and t.relname like 'orders'
order by t.relname, i.relname, array_position(ix.indkey,a.attnum)
【讨论】:
【参考方案5】:@cope360 的一点修改答案:
create table test (a int, b int, c int, constraint pk_test primary key(c, a, b));
select i.relname as index_name,
ix.indisunique as is_unique,
a.attname as column_name,
from pg_class c
inner join pg_index ix on c.oid=ix.indrelid
inner join pg_class i on ix.indexrelid=i.oid
inner join pg_attribute a on a.attrelid=c.oid and a.attnum=any(ix.indkey)
where c.oid='public.test'::regclass::oid
order by array_position(ix.indkey, a.attnum) asc;
这将以正确的顺序显示索引列:
index_name is_unique column_name
pk_test true c
pk_test true a
pk_test true b
【讨论】:
使用“left join pg_attribute”也会在计算列上显示索引,当然还有一个 NULL column_name。【参考方案6】:扩展到@Cope360 的好答案。要获取某个表(如果它们的表名相同但架构不同),只需使用表 OID。
select
t.relname as table_name
,i.relname as index_name
,a.attname as column_name
,a.attrelid tableid
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 'tbassettype'
and a.attrelid = '"dbLegal".tbassettype'::regclass
order by
t.relname,
i.relname;
说明:我在模式“dbAsset”和“dbLegal”中都有表名“tbassettype”。要仅获取 dbLegal 上的表,只需让 a.attrelid = 它的 OID。
【讨论】:
【参考方案7】:PostgreSQL (pg_indexes):
SELECT * FROM pg_indexes WHERE tablename = 'mytable';
MySQL (SHOW INDEX):
SHOW INDEX FROM mytable;
【讨论】:
这是最直接的答案,也是回答“我的列被索引了吗?”这个问题时最有趣的答案。 PostgreSQL:SELECT COUNT(indexname) AS indexcount FROM pg_indexes WHERE tablename='mytablename' AND indexdef LIKE '%mycolumnname%' ;
并验证 indexcount>0
。 mySQL: SHOW INDEX FROM mytablename WHERE Column_name='mycolumnname' ;
并验证结果集不为空。
尽管在检索有关索引的快速信息方面这是一个非常有用的答案,但它不能回答原始问题,因为pg_indexes
视图不提供列名。 postgresql.org/docs/current/view-pg-indexes.html【参考方案8】:
我认为此线程上尚不存在此版本:它提供了列名列表以及索引的 ddl。
CREATE OR REPLACE VIEW V_TABLE_INDEXES AS
SELECT
n.nspname as "schema"
,t.relname as "table"
,c.relname as "index"
,i.indisunique AS "is_unique"
,array_to_string(array_agg(a.attname), ', ') as "columns"
,pg_get_indexdef(i.indexrelid) as "ddl"
FROM pg_catalog.pg_class c
JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
JOIN pg_catalog.pg_index i ON i.indexrelid = c.oid
JOIN pg_catalog.pg_class t ON i.indrelid = t.oid
JOIN pg_attribute a ON a.attrelid = t.oid AND a.attnum = ANY(i.indkey)
WHERE c.relkind = 'i'
and n.nspname not in ('pg_catalog', 'pg_toast')
and pg_catalog.pg_table_is_visible(c.oid)
GROUP BY
n.nspname
,t.relname
,c.relname
,i.indisunique
,i.indexrelid
ORDER BY
n.nspname
,t.relname
,c.relname;
我发现使用函数的索引不会链接到列名,所以偶尔你会发现索引列表,例如一列名实际上是使用 3.
例子:
CREATE INDEX ui1 ON table1 (coalesce(col1,''),coalesce(col2,''),col3)
查询仅返回“col3”作为索引上的列,但 DDL 显示索引中使用的完整列集。
【讨论】:
【参考方案9】:这是一个包装 cope360 答案的函数:
CREATE OR REPLACE FUNCTION getIndices(_table_name varchar)
RETURNS TABLE(table_name varchar, index_name varchar, column_name varchar) AS $$
BEGIN
RETURN QUERY
select
t.relname::varchar as table_name,
i.relname::varchar as index_name,
a.attname::varchar 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 = _table_name
order by
t.relname,
i.relname;
END;
$$ LANGUAGE plpgsql;
用法:
select * from getIndices('<my_table>')
【讨论】:
没有列出使用函数的索引部分(例如“upper(field_name)”)。【参考方案10】:@cope360 的出色答案,已转换为使用连接语法。
select t.relname as table_name
, i.relname as index_name
, array_to_string(array_agg(a.attname), ', ') as column_names
from pg_class t
join pg_index ix
on t.oid = ix.indrelid
join pg_class i
on i.oid = ix.indexrelid
join pg_attribute a
on a.attrelid = t.oid
and a.attnum = ANY(ix.indkey)
where t.relkind = 'r'
and t.relname like 'test%'
group by t.relname
, i.relname
order by t.relname
, i.relname
;
【讨论】:
【参考方案11】:与已接受的答案类似,但在 pg_attribute 上将 left join 作为普通连接或使用 pg_attribute 进行查询不会给出如下索引:
create unique index unique_user_name_index on users (lower(name))
select
row_number() over (order by c.relname),
c.relname as index,
t.relname as table,
array_to_string(array_agg(a.attname), ', ') as column_names
from pg_class c
join pg_index i on c.oid = i.indexrelid and c.relkind='i' and c.relname not like 'pg_%'
join pg_class t on t.oid = i.indrelid
left join pg_attribute a on a.attrelid = t.oid and a.attnum = ANY(i.indkey)
group by t.relname, c.relname order by c.relname;
【讨论】:
很好,但是如何获取有关“lower(column_name")”的信息【参考方案12】:请尝试以下查询以深入了解所需的索引
查询如下-我亲自尝试过并经常使用它。
SELECT n.nspname as "Schema",
c.relname as "Name",
CASE c.relkind WHEN 'r' THEN 'table' WHEN 'v' THEN 'view' WHEN 'i'
THEN 'index' WHEN 'S' THEN 'sequence' WHEN 's' THEN 'special' END as "Type",
u.usename as "Owner",
c2.relname as "Table"
FROM pg_catalog.pg_class c
JOIN pg_catalog.pg_index i ON i.indexrelid = c.oid
JOIN pg_catalog.pg_class c2 ON i.indrelid = c2.oid
LEFT JOIN pg_catalog.pg_user u ON u.usesysid = c.relowner
LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
WHERE c.relkind IN ('i','')
AND n.nspname NOT IN ('pg_catalog', 'pg_toast')
AND pg_catalog.pg_table_is_visible(c.oid)
AND c2.relname like '%agg_transaction%' --table name
AND nspname = 'edjus' -- schema name
ORDER BY 1,2;
【讨论】:
【参考方案13】:在使用索引时,在索引中构建列的顺序与列本身一样重要。
以下查询以排序方式列出给定表的所有索引及其所有列。
SELECT
table_name,
index_name,
string_agg(column_name, ',')
FROM (
SELECT
t.relname AS table_name,
i.relname AS index_name,
a.attname AS column_name,
(SELECT i
FROM (SELECT
*,
row_number()
OVER () i
FROM unnest(indkey) WITH ORDINALITY AS a(v)) a
WHERE v = attnum)
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 'tablename'
ORDER BY table_name, index_name, i
) raw
GROUP BY table_name, index_name
【讨论】:
为什么 OP 应该“试试这个”? 好的答案将始终解释所做的工作以及这样做的原因,不仅适用于 OP,而且适用于可能会发现此问题并正在阅读您的答案的 SO 的未来访问者。 序数的i
非常漂亮。它确保列以正确的顺序陈述。
这是唯一对我有用的答案。列顺序很关键。 (如果您不相信我,请在电话簿中查找所有名字为 Frank 的人。)【参考方案14】:
此命令也显示表变量、索引和约束的视图
=# \d table_name;
例子:
testannie=# \d dv.l_customer_account;
【讨论】:
【参考方案15】:一个简单的解决方案怎么样:
SELECT
t.relname table_name,
ix.relname index_name,
indisunique,
indisprimary,
regexp_replace(pg_get_indexdef(indexrelid), '.*\((.*)\)', '\1') columns
FROM pg_index i
JOIN pg_class t ON t.oid = i.indrelid
JOIN pg_class ix ON ix.oid = i.indexrelid
WHERE t.relname LIKE 'test%'
`
【讨论】:
喜欢这个解决方案。不幸的是,带有 where 子句的索引会失败。 (或其他括号) 我更改为在开始时不跳过括号,中间不捕获括号,然后丢弃所有内容。'^[^\)]*\(([^\)]*)\).*$'
【参考方案16】:
只要做:\d table_name
但我不确定你的意思是关于列的信息不存在。
例如:
# \d pg_class
Table "pg_catalog.pg_class"
Column | Type | Modifiers
-----------------+-----------+-----------
relname | name | not null
relnamespace | oid | not null
reltype | oid | not null
reloftype | oid | not null
relowner | oid | not null
relam | oid | not null
relfilenode | oid | not null
reltablespace | oid | not null
relpages | integer | not null
reltuples | real | not null
reltoastrelid | oid | not null
reltoastidxid | oid | not null
relhasindex | boolean | not null
relisshared | boolean | not null
relistemp | boolean | not null
relkind | "char" | not null
relnatts | smallint | not null
relchecks | smallint | not null
relhasoids | boolean | not null
relhaspkey | boolean | not null
relhasexclusion | boolean | not null
relhasrules | boolean | not null
relhastriggers | boolean | not null
relhassubclass | boolean | not null
relfrozenxid | xid | not null
relacl | aclitem[] |
reloptions | text[] |
Indexes:
"pg_class_oid_index" UNIQUE, btree (oid)
"pg_class_relname_nsp_index" UNIQUE, btree (relname, relnamespace)
它清楚地显示给定索引的列在此表上。
【讨论】:
我希望有一些东西可以让我在一张桌子上做所有的索引,但你是对的,\d index_name
确实有这些信息。所以我可以查找表上的索引,然后查找详细信息。通过不显示列,我的意思是我查看了由\d table
名称生成的 SQL,但列列表的来源对我来说并不明显。我认为它正在从索引定义中解析出来,我不想这样做。
我使用的是 AWS RDS PostgreSQL 9.6.5,\d table
没有显示任何索引,但 \di
确实显示了所有索引。【参考方案17】:
查询结果:
table | column | type | notnull | index_name | is_index | primarykey | uniquekey | default
-------+----------------+------------------------+---------+--------------+----------+- -----------+-----------+---------
nodes | dns_datacenter | character varying(255) | f | | f | f | f |
nodes | dns_name | character varying(255) | f | dns_name_idx | t | f | f |
nodes | id | uuid | t | nodes_pkey | t | t | t |
(3 rows)
查询:
SELECT
c.relname AS table,
f.attname AS column,
pg_catalog.format_type(f.atttypid,f.atttypmod) AS type,
f.attnotnull AS notnull,
i.relname as index_name,
CASE
WHEN i.oid<>0 THEN 't'
ELSE 'f'
END AS is_index,
CASE
WHEN p.contype = 'p' THEN 't'
ELSE 'f'
END AS primarykey,
CASE
WHEN p.contype = 'u' THEN 't'
WHEN p.contype = 'p' THEN 't'
ELSE 'f'
END AS uniquekey,
CASE
WHEN f.atthasdef = 't' THEN d.adsrc
END AS default FROM pg_attribute f
JOIN pg_class c ON c.oid = f.attrelid
JOIN pg_type t ON t.oid = f.atttypid
LEFT JOIN pg_attrdef d ON d.adrelid = c.oid AND d.adnum = f.attnum
LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
LEFT JOIN pg_constraint p ON p.conrelid = c.oid AND f.attnum = ANY (p.conkey)
LEFT JOIN pg_class AS g ON p.confrelid = g.oid
LEFT JOIN pg_index AS ix ON f.attnum = ANY(ix.indkey) and c.oid = f.attrelid and c.oid = ix.indrelid
LEFT JOIN pg_class AS i ON ix.indexrelid = i.oid
WHERE c.relkind = 'r'::char
AND n.nspname = 'public' -- Replace with Schema name
--AND c.relname = 'nodes' -- Replace with table name, or Comment this for get all tables
AND f.attnum > 0
ORDER BY c.relname,f.attname;
【讨论】:
不错,但是列的“列”名称是保留字。架构的 IDEM,应使用 column_name【参考方案18】:如果您想在索引中保留列顺序,这是一种(非常丑陋的)方法:
select table_name,
index_name,
array_agg(column_name)
from (
select
t.relname as table_name,
i.relname as index_name,
a.attname as column_name,
unnest(ix.indkey) as unn,
a.attnum
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.relnamespace = <oid of the schema you're interested in>
order by
t.relname,
i.relname,
generate_subscripts(ix.indkey,1)) sb
where unn = attnum
group by table_name, index_name
列顺序存储在 pg_index.indkey 列中,所以我按该数组中的下标排序。
【讨论】:
【参考方案19】:结合其他代码创建视图:
CREATE OR REPLACE VIEW view_index AS
SELECT
n.nspname as "schema"
,t.relname as "table"
,c.relname as "index"
,pg_get_indexdef(indexrelid) as "def"
FROM pg_catalog.pg_class c
JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
JOIN pg_catalog.pg_index i ON i.indexrelid = c.oid
JOIN pg_catalog.pg_class t ON i.indrelid = t.oid
WHERE c.relkind = 'i'
and n.nspname not in ('pg_catalog', 'pg_toast')
and pg_catalog.pg_table_is_visible(c.oid)
ORDER BY
n.nspname
,t.relname
,c.relname;
【讨论】:
【参考方案20】:创建一些测试数据...
create table test (a int, b int, c int, constraint pk_test primary key(a, b));
create table test2 (a int, b int, c int, constraint uk_test2 unique (b, c));
create table test3 (a int, b int, c int, constraint uk_test3b unique (b), constraint uk_test3c unique (c),constraint uk_test3ab unique (a, b));
列出索引和索引的列:
select
t.relname as table_name,
i.relname as index_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 'test%'
order by
t.relname,
i.relname;
table_name | index_name | column_name
------------+------------+-------------
test | pk_test | a
test | pk_test | b
test2 | uk_test2 | b
test2 | uk_test2 | c
test3 | uk_test3ab | a
test3 | uk_test3ab | b
test3 | uk_test3b | b
test3 | uk_test3c | c
汇总列名:
select
t.relname as table_name,
i.relname as index_name,
array_to_string(array_agg(a.attname), ', ') as column_names
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 'test%'
group by
t.relname,
i.relname
order by
t.relname,
i.relname;
table_name | index_name | column_names
------------+------------+--------------
test | pk_test | a, b
test2 | uk_test2 | b, c
test3 | uk_test3ab | a, b
test3 | uk_test3b | b
test3 | uk_test3c | c
【讨论】:
对于任何试图在填充数据库中查找索引的人:此查询效果很好,但将and t.relname like 'test%'
行更改为您想要的表,或完全删除该行以查找其中的所有索引你的数据库。
有人能解释一下relkind='r'
是什么意思吗?
@Qwery,请参阅 pg_class r = ordinary table, i = index, S = sequence, v = view, c = composite type, t = TOAST table
的文档。
有没有办法同时判断密钥的唯一性?
要查看索引唯一性也选择ix.indisunique
【参考方案21】:
一些示例数据...
create table test (a int, b int, c int, constraint pk_test primary key(a, b));
create table test2 (a int, b int, c int, constraint uk_test2 unique (b, c));
create table test3 (a int, b int, c int, constraint uk_test3b unique (b), constraint uk_test3c unique (c), constraint uk_test3ab unique (a, b));
使用pg_get_indexdef
函数:
select pg_get_indexdef(indexrelid) from pg_index where indrelid = 'test'::regclass;
pg_get_indexdef
--------------------------------------------------------
CREATE UNIQUE INDEX pk_test ON test USING btree (a, b)
(1 row)
select pg_get_indexdef(indexrelid) from pg_index where indrelid = 'test2'::regclass;
pg_get_indexdef
----------------------------------------------------------
CREATE UNIQUE INDEX uk_test2 ON test2 USING btree (b, c)
(1 row)
select pg_get_indexdef(indexrelid) from pg_index where indrelid ='test3'::regclass;
pg_get_indexdef
------------------------------------------------------------
CREATE UNIQUE INDEX uk_test3b ON test3 USING btree (b)
CREATE UNIQUE INDEX uk_test3c ON test3 USING btree (c)
CREATE UNIQUE INDEX uk_test3ab ON test3 USING btree (a, b)
(3 rows)
【讨论】:
简单有效! 太棒了。我很幸运我已经滚动到这个答案。【参考方案22】:\d table_name
显示来自psql
的此信息,但如果您想使用 SQL 从数据库中获取此类信息,请查看Extracting META information from PostgreSQL。
我在utility to report some info from db schema 中使用这些信息来比较测试和生产环境中的 PostgreSQL 数据库。
【讨论】:
您从 Postgres 中提取元信息的链接正是我想要的!使用这个线程中的提示和一些挖掘,我非常接近他在那篇帖子中使用的查询,但很高兴能把它全部布置成这样。 我使用的是 AWS RDS PostgreSQL 9.6.5,\d table
没有显示任何索引,但 \di
确实显示了所有索引。
@HendyIrawan 它显然会受到其他设置的影响。就像我想知道您是否启用了“仅元组”模式(由\t
切换)。启用“仅元组”后,我不会从 \d
获取索引,而禁用“仅元组”时,我会这样做。这适用于 psql (PostgreSQL) 9.6.15。【参考方案23】:
\d tablename
为我显示 8.3.8 版本的列名。
"username_idx" UNIQUE, btree (username), tablespace "alldata1"
【讨论】:
【参考方案24】:原始信息位于pg_index。
【讨论】:
有趣。特别是indkey
:“这是一个 indnatts 值数组,指示该索引索引哪些表列。例如,值 1 3 表示第一和第三表列构成索引键。此数组中的零表示对应的索引属性是对表列的表达式,而不是简单的列引用"以上是关于在 PostgreSQL 中列出具有索引的列的主要内容,如果未能解决你的问题,请参考以下文章