Список столбцов с индексами в PostgreSQL

192

Я хотел бы получить столбцы, в которых указатель включен в 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?

Я пробовал \d в командной строке psql (с параметром -E для отображения SQL), но он не отображает информацию, которую я ищу.

Обновление: Спасибо всем, кто добавил ответы. cope360 дал мне именно то, что я искал, но несколько человек подхватили очень полезные ссылки. В дальнейшем обратитесь к документации для pg_index (через Милен А. Радев) и очень полезная статья Извлечение информации META из PostgreSQL (через Michał Niklas).

  • 0
    Просто чтобы уточнить: вы хотите, чтобы ваша программа могла во время выполнения выяснить, какие столбцы индексируются, верно? В отличие от вас знание программирования.
  • 0
    Да исправить. В идеале мне нужен оператор SQL, в котором перечислены ТОЛЬКО столбцы, к которым относится индекс. Но я знаю, что PostgreSQL сложнее, чем MySQL, и индекс может быть для функции и т. Д.
Теги:
indexing

23 ответа

230
Лучший ответ

Создайте некоторые тестовые данные...

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
  • 22
    Для тех, кто пытается найти индексы в заполненной базе данных: этот запрос отлично работает, но измените and t.relname like 'test%' на таблицы, которые вы хотите, или полностью удалите эту строку, чтобы найти все индексы в вашей базе данных. ,
  • 1
    Может кто-нибудь объяснить, что relkind='r' ?
Показать ещё 8 комментариев
133

\d table_name показывает эту информацию из psql, но если вы хотите получить такую ​​информацию из базы данных с помощью SQL, то посмотрите Извлечение информации META из PostgreSQL.

Я использую такую ​​информацию в своей утилите чтобы сообщить некоторую информацию из схемы db для сравнения баз данных PostgreSQL в тестовых и производственных средах.

  • 0
    Ваша ссылка на извлечение метаинформации из Postgres - это именно то, что я искал! Используя подсказки в этой теме и некоторые раскопки, я довольно близко подошел к запросу, который он использует в этом посте, но приятно, что все это изложено так.
  • 0
    Я использую AWS RDS PostgreSQL 9.6.5, и \d table не показывает никаких индексов, однако \di показывает все индексы.
122

PostgreSQL (pg_indexes):

SELECT * FROM pg_indexes WHERE tablename = 'mytable';

MySQL (ПОКАЗАТЬ ИНДЕКС):

SHOW INDEX FROM mytable;
  • 3
    Это самый простой ответ, и самый интересный с точки зрения ответа на вопрос «Индексируется ли моя колонка?» 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' ; и проверьте набор результатов не пустой.
  • 0
    Хотя это очень полезный ответ с точки зрения получения быстрой информации об индексах, он не отвечает на исходный вопрос, потому что представление pg_indexes не предоставляет имен столбцов. postgresql.org/docs/current/view-pg-indexes.html
73

Просто выполните: \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)

Он четко показывает, какие столбцы указаны в этой таблице.

  • 0
    Я надеялся на что-то, что позволило бы мне сделать все индексы для таблицы, но вы правы, \d index_name действительно имеет информацию. Так что я могу посмотреть на индексы в таблице, а затем посмотреть детали. Не показывая столбцы, я имею в виду, что я посмотрел на SQL, сгенерированный именем \d table и для меня не очевидно, откуда берется список столбцов. Я думаю, что это анализируется из определения индекса, что я предпочел бы не делать.
  • 0
    Я использую AWS RDS PostgreSQL 9.6.5, и \d table не показывает никаких индексов, однако \di показывает все индексы.
30

# \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 команд, которые будут перечислены все отношения текущего г atabase. Таким образом, \di, конечно, стоять на "показать мне это d atabases I ndexes".

Набрав \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 вы можете легко найти справку о наборе команд \? ,

  • 2
    Но он не показывает имена столбцов, по которым создаются индексы. Составной индекс первичных ключей имеет много столбцов, и их нельзя увидеть.
18

В сочетании с другим кодом и созданием представления:

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;
11

Некоторые примеры данных...

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)
  • 0
    Просто и эффективно!
  • 0
    Просто потрясающе. Мне повезло, что я прокрутил этот ответ.
7

В этих командах также отображается представление переменных таблиц, индексов и ограничений

=# \d table_name;

Пример:

testannie=# \d dv.l_customer_account;
7

\d tablename показывает имена столбцов для меня на версии 8.3.8.

 "username_idx" UNIQUE, btree (username), tablespace "alldata1"
5

РЕЗУЛЬТАТ ЗАПРОСА:

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)

QUERY

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;
  • 0
    хороший, однако имя столбца для столбца является зарезервированным словом. IDEM для схемы, следует использовать column_name
5

Необработанная информация находится в pg_index.

  • 0
    Интересно. В частности, indkey : «Это массив значений indnatts, которые указывают, какие столбцы таблицы этот индекс индексирует. Например, значение 1 3 будет означать, что первый и третий столбцы таблицы составляют ключ индекса. Ноль в этом массиве указывает, что соответствующий атрибут индекса является выражением над столбцами таблицы, а не простой ссылкой на столбец "
2

Если вы хотите сохранить порядок столбцов в индексе, здесь (очень уродливый) способ сделать это:

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, поэтому я упорядочивается по индексам из этого массива.

1

Здесь функция, которая завершает ответ 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>')
  • 0
    Не перечислил части моих индексов, которые используют функции (например, "upper (field_name)").
1

Подобно принятому ответу, но слева присоединяется к pg_attribute, поскольку обычное соединение или запрос с 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;
  • 0
    Хорошая заметка, но как получить информацию о том, что "lower (column_name") "
1

Пожалуйста, попробуйте выполнить запрос ниже, чтобы развернуть его до требуемого индекса

Запрос ниже: я пробовал это лично и часто использовал его.

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;
1

При игре с индексами порядок столбцов, построенных в индексе, важен как сами столбцы.

В следующем запросе отсортированы все индексы для данной таблицы и всех их столбцов.

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
  • 2
    Почему ОП "попробовать это"? Хороший ответ всегда будет содержать объяснение того, что было сделано и почему это было сделано таким образом, не только для ОП, но и для будущих посетителей SO, которые могут найти этот вопрос и прочитать ваш ответ.
  • 0
    i для ординальности очень гладко. Это гарантирует, что столбцы указаны в правильном порядке.
0

Принятый ответ @cope360 хорош, но я хотел что-то более похожее на 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)
0
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)
0

Немного модифицированный ответ @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
  • 0
    Использование «left join pg_attribute» также покажет индексы для вычисляемых столбцов, конечно, с NULL column_name.
0

Продлите до хорошего ответа @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;

Объясните: у меня есть имя таблицы 'tbassettype' в обеих схемах 'dbAsset' и 'dbLegal'. Чтобы получить только таблицу на dbLegal, просто позвольте a.attrelid = его OID.

0

Я не думаю, что эта версия существует в этом потоке: она содержит как список имен столбцов, так и индекс 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 показывает полный набор столбцов, используемых в индексе.

0

@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
;
0

Как насчет простого решения:

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

`

  • 0
    Люблю это решение. К сожалению, это не с индексами, которые имеют предложения where. (или другие скобки)
  • 0
    Я изменил, чтобы не пропускать парены в начале, и не захватывать парни в середине, и бросать все после этого. '^[^\)]*\(([^\)]*)\).*$'

Ещё вопросы

Сообщество Overcoder
Наверх
Меню