Лучше удалить неиспользуемые индексы? - PullRequest
1 голос
/ 18 марта 2020

Результат запроса ниже показывает историю статистики индексов. Будет ли лучше удалить индексы, которые возвращают значение 0 при TotalNumberOfScan?

SELECT
pt.tablename AS TableName
,t.indexname AS IndexName
,pc.reltuples AS TotalRows
,pg_size_pretty(pg_relation_size(quote_ident(pt.tablename)::text)) AS TableSize
,pg_size_pretty(pg_relation_size(quote_ident(t.indexrelname)::text)) AS IndexSize
,t.idx_scan AS TotalNumberOfScan
,t.idx_tup_read AS TotalTupleRead
,t.idx_tup_fetch AS TotalTupleFetched
FROM pg_tables AS pt
LEFT OUTER JOIN pg_class AS pc 
ON pt.tablename=pc.relname
LEFT OUTER JOIN
( 
SELECT 
    pc.relname AS TableName
    ,pc2.relname AS IndexName
    ,psai.idx_scan
    ,psai.idx_tup_read
    ,psai.idx_tup_fetch
    ,psai.indexrelname 
FROM pg_index AS pi
JOIN pg_class AS pc 
    ON pc.oid = pi.indrelid
JOIN pg_class AS pc2 
    ON pc2.oid = pi.indexrelid
JOIN pg_stat_all_indexes AS psai 
    ON pi.indexrelid = psai.indexrelid 
)AS T
ON pt.tablename = T.TableName
WHERE pt.schemaname='public'
ORDER BY 1;

Ответы [ 2 ]

4 голосов
/ 18 марта 2020

Определенно вы должны удалить индексы, которые вы не используете. Индексы ускоряют некоторые операции, но за отдельную плату - их нужно обновлять каждый раз, когда происходит вставка, удаление или некоторые обновления.

Здесь - отличный пост о стоимости поддержки дополнительных индексы при обновлении, здесь при удалении и здесь при вставке. Например, время вставки в таблицу с двумя индексами почти в два раза больше, чем для одной таблицы с одним индексом.

2 голосов
/ 18 марта 2020

Вот мой золотой стандарт для поиска всех бесполезных индексов:

SELECT s.schemaname,
       s.relname AS tablename,
       s.indexrelname AS indexname,
       pg_relation_size(s.indexrelid) AS index_size
FROM pg_catalog.pg_stat_user_indexes s
   JOIN pg_catalog.pg_index i ON s.indexrelid = i.indexrelid
WHERE s.idx_scan = 0      -- has never been scanned
  AND 0 <>ALL (i.indkey)  -- no index column is an expression
  AND NOT i.indisunique   -- is not a UNIQUE index
  AND NOT EXISTS          -- does not enforce a constraint
         (SELECT 1 FROM pg_catalog.pg_constraint c
          WHERE c.conindid = s.indexrelid)
ORDER BY pg_relation_size(s.indexrelid) DESC;

Необходимо учитывать, что индексы используются не только для ускорения WHERE и ORDER BY предложений:

  • Многие ограничения реализованы индексами, например, первичными ключами.

  • Индексы в выражениях заставляют PostgreSQL собирать статистику для индексированного выражения, что может помочь оптимизатору .

Подробнее см. мой блог .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...