Аналіз використання індексу PostgreSQL


86

Чи існує інструмент або метод для аналізу Postgres та визначення того, які відсутні індекси слід створити, а які невикористані індекси видалити? У мене є невеликий досвід роботи з інструментом "Профайлер" для SQLServer, але я не знаю подібного інструменту, включеного до Postgres.


Так воно і є. Давно не дивився на це. Оновив прийняту відповідь.
Черін

Відповіді:


164

Мені подобається це, щоб знайти відсутні індекси:

SELECT
  relname                                               AS TableName,
  to_char(seq_scan, '999,999,999,999')                  AS TotalSeqScan,
  to_char(idx_scan, '999,999,999,999')                  AS TotalIndexScan,
  to_char(n_live_tup, '999,999,999,999')                AS TableRows,
  pg_size_pretty(pg_relation_size(relname :: regclass)) AS TableSize
FROM pg_stat_all_tables
WHERE schemaname = 'public'
      AND 50 * seq_scan > idx_scan -- more then 2%
      AND n_live_tup > 10000
      AND pg_relation_size(relname :: regclass) > 5000000
ORDER BY relname ASC;

Це перевіряє, чи є більше послідовних сканувань, ніж сканування індексу. Якщо таблиця мала, вона ігнорується, оскільки, здається, Postgres надає перевагу скануванню послідовностей для них.

Над запитом виявляються відсутні індекси.

Наступним кроком буде виявлення відсутніх комбінованих індексів. Я думаю, це непросто, але здійсненно. Можливо, аналізуючи повільні запити ... Я чув, що pg_stat_statements може допомогти ...


15
Щоб зробити цю роботу з цитованими ідентифікаторами, змініть запит на: SELECT relname, seq_scan-idx_scan AS too_much_seq, case when seq_scan-idx_scan>0 THEN 'Missing Index?' ELSE 'OK' END, pg_relation_size(relid::regclass) AS rel_size, seq_scan, idx_scan FROM pg_stat_all_tables WHERE schemaname='public' AND pg_relation_size(relid::regclass)>80000 ORDER BY too_much_seq DESC;
Містер Мускат

10
Висновок цього запиту слід пояснити , щоб зробити відповідь більш корисним
ЄКР

До точки @cen, коли too_much_seqце позитивно і велике значення, ви повинні турбуватися.
mountainclimber11

1
@KishoreKumar Я думаю, статистика в postgres все ще містить запити, які були виконані до того, як ви оновили свій індекс. Залежно від вашого трафіку статистика знову буде нормальною через кілька годин.
guettli

1
::regclassне працюватиме з ідентифікаторами великих літер, @Mr. Ондатра має хороше рішення, її також можна використовувати ('"' || relname || '"')::regclassзамість неї.
Адріен


10

Щодо визначення відсутніх індексів підхід .... Ні. Але є деякі плани спростити це в майбутньому випуску, наприклад, псевдоіндекси та машиночитаний EXPLAIN.

Наразі вам доведеться EXPLAIN ANALYZEпогано виконувати запити, а потім вручну визначити найкращий маршрут. Деякі аналізатори журналів, такі як pgFouine, можуть допомогти визначити запити.

Що стосується невикористаного індексу, ви можете використати щось на зразок наступного, щоб допомогти їх ідентифікувати:

select * from pg_stat_all_indexes where schemaname <> 'pg_catalog';

Це допоможе визначити кортежі, прочитані, відскановані, отримані.


Френк Хейкенс також вказує на деякі хороші місця в інших місцях для запитів щодо поточного використання індексу.
rfusca

8

Ще одним новим та цікавим інструментом для аналізу PostgreSQL є PgHero . Він більше зосереджений на налаштуванні бази даних і робить численні аналізи та пропозиції.

скріншот


6

Ви можете використовувати нижченаведений запит, щоб знайти використання індексу та розмір індексу:

Довідка взята з цього блогу.

SELECT
    pt.tablename AS TableName
    ,t.indexname AS IndexName
    ,to_char(pc.reltuples, '999,999,999,999') 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
    ,to_char(t.idx_scan, '999,999,999,999') AS TotalNumberOfScan
    ,to_char(t.idx_tup_read, '999,999,999,999') AS TotalTupleRead
    ,to_char(t.idx_tup_fetch, '999,999,999,999') 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;

4

Існує кілька посилань на сценарії, які допоможуть вам знайти невикористані індекси у вікі PostgreSQL . Основна техніка полягає в тому, щоб розглядати pg_stat_user_indexesі шукати ті, де idx_scanкількість випадків, коли цей індекс був використаний для відповіді на запити, дорівнює нулю або, принаймні, дуже низькій. Якщо програма змінилася, і раніше використовуваний індекс, ймовірно, не зараз, вам іноді доводиться запускати, pg_stat_reset()щоб повернути всю статистику до 0, а потім збирати нові дані; Ви можете зберегти поточні значення для всього і замість цього обчислити дельту, щоб це зрозуміти.

Поки що немає хороших інструментів, які пропонують відсутні індекси. Одним із підходів є реєстрація запущених запитів та аналіз того, які з них виконуються довго, використовуючи інструмент аналізу журналу запитів, такий як pgFouine або pqa. Додаткову інформацію див. У розділі " Журналювання складних запитів ".

Інший підхід полягає у перегляді pg_stat_user_tablesта пошуку таблиць, які мають велику кількість послідовних сканувань проти них, де seq_tup_fetchце велике. Коли використовується індекс, idx_fetch_tupнатомість кількість збільшується. Це може підказати вам, коли таблиця проіндексована недостатньо добре, щоб відповідати на запити щодо неї.

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



1

PoWA здається цікавим інструментом для PostgreSQL 9.4+. Він збирає статистичні дані, візуалізує їх та пропонує індекси. Він використовує pg_stat_statementsрозширення.

PoWA - це аналізатор робочого навантаження PostgreSQL, який збирає статистику продуктивності та надає діаграми та графіки в режимі реального часу, що допомагає контролювати та налаштовувати ваші сервери PostgreSQL. Це схоже на Oracle AWR або SQL Server MDW.


0
CREATE EXTENSION pgstattuple; 
CREATE TABLE test(t INT); 
INSERT INTO test VALUES(generate_series(1, 100000)); 
SELECT * FROM pgstatindex('test_idx'); 

version            | 2 
tree_level         | 2 
index_size         | 105332736 
root_block_no      | 412 
internal_pages     | 40 
leaf_pages         | 12804 
empty_pages        | 0 
deleted_pages      | 13 
avg_leaf_density   | 9.84 
leaf_fragmentation | 21.42 

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.