Заметки о данных и инженерии

Индексы, которые не используются

Индексы обычно только добавляют: где-то запрос притормозил — повесили индекс, стало быстрее. Удаляет их редко кто. В итоге за пару лет накапливается слой, о котором никто не помнит.

Решил посчитать. Запрос, который показывает, сколько раз индексом реально пользовались:

SELECT schemaname, relname AS table_name, indexrelname AS index_name,
       idx_scan AS scans,
       pg_size_pretty(pg_relation_size(indexrelid)) AS size
FROM pg_stat_user_indexes
WHERE idx_scan = 0
  AND indexrelid NOT IN (SELECT conindid FROM pg_constraint)
ORDER BY pg_relation_size(indexrelid) DESC;

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

Прежде чем удалять

Пара оговорок, о которые легко споткнуться:

Обратная сторона: чего не хватает

Заодно полезно посмотреть, где идут последовательные сканы по крупным таблицам:

SELECT relname, seq_scan, idx_scan,
       pg_size_pretty(pg_relation_size(relid)) AS size
FROM pg_stat_user_tables
WHERE seq_scan > idx_scan AND pg_relation_size(relid) > 100e6
ORDER BY seq_scan DESC;

Если большая таблица регулярно читается целиком — либо не хватает индекса, либо запрос написан так, что существующий не применяется (функция над колонкой, несовпадение типов, LIKE '%...').

Удалять индексы стоит по одному и с паузой. Если что-то замедлится — сразу понятно, какой вернуть.

← ко всем записям