web-dev-qa-db-fra.com

Analyse de l'utilisation des index PostgreSQL

Existe-t-il un outil ou une méthode pour analyser PostgreSQL et déterminer quels index manquants doivent être créés et quels index inutilisés doivent être supprimés? J'ai un peu d'expérience avec l'outil "profileur" pour SQLServer, mais je ne connais pas d'outil similaire inclus avec Postgres.

77
Cerin

J'aime cela pour trouver les index manquants:

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;

Cela vérifie s'il y a plus d'analyses de séquence que d'index. Si la table est petite, elle est ignorée, car Postgres semble leur préférer les analyses de séquence.

La requête ci-dessus révèle des index manquants.

La prochaine étape serait de détecter les index combinés manquants. Je suppose que ce n'est pas facile, mais faisable. Peut-être qu'analyser les requêtes lentes ... J'ai entendu pg_stat_statements pourrait aider ...

149
guettli

Vérifiez les statistiques. pg_stat_user_tables et pg_stat_user_indexes sont ceux pour commencer.

Voir " The Statistics Collector ".

19
Frank Heikens

Sur l'approche de déterminer les indices manquants .... Non. Mais il est prévu de faciliter cela dans les versions futures, comme les pseudo-index et EXPLAIN lisibles par machine.

Actuellement, vous devrez EXPLAIN ANALYZE requêtes peu performantes, puis déterminer manuellement le meilleur itinéraire. Certains analyseurs de journaux comme pgFouine peuvent aider à déterminer les requêtes.

En ce qui concerne un index inutilisé, vous pouvez utiliser quelque chose comme le suivant pour aider à les identifier:

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

Cela aidera à identifier les tuples lus, scannés, récupérés.

8
rfusca

Un autre nouvel outil intéressant pour analyser PostgreSQL est PgHero . Il est plus axé sur le réglage de la base de données et fait de nombreuses analyses et suggestions.

screenshot

6
n1000

Il existe plusieurs liens vers des scripts qui vous aideront à trouver des index inutilisés sur le wiki PostgreSQL . La technique de base consiste à examiner pg_stat_user_indexes Et à rechercher celles où idx_scan, Le nombre de fois où cet index a été utilisé pour répondre à des requêtes, est nul ou du moins très faible. Si l'application a changé et qu'un index précédemment utilisé ne l'est probablement pas maintenant, vous devez parfois exécuter pg_stat_reset() pour ramener toutes les statistiques à 0, puis collecter de nouvelles données; vous pouvez enregistrer les valeurs actuelles pour tout et calculer un delta à la place pour le comprendre.

Il n'y a pas encore de bons outils disponibles pour suggérer des index manquants. Une approche consiste à consigner les requêtes que vous exécutez et à analyser celles qui prennent beaucoup de temps à exécuter à l'aide d'un outil d'analyse du journal des requêtes comme pgFouine ou pqa. Voir " Journalisation des requêtes difficiles " pour plus d'informations.

L'autre approche consiste à examiner pg_stat_user_tables Et à rechercher des tables contenant un grand nombre d'analyses séquentielles, où seq_tup_fetch Est grand. Lorsqu'un index est utilisé, le nombre idx_fetch_tup Est augmenté à la place. Cela peut vous indiquer quand une table n'est pas suffisamment indexée pour répondre aux requêtes.

Vous pensez réellement sur quelles colonnes vous devez indexer? Cela ramène généralement à nouveau à l'analyse du journal des requêtes.

3
Greg Smith

Vous pouvez utiliser la requête ci-dessous pour trouver l'utilisation et la taille de l'index:

La référence est tirée de ce blog.

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;
3
Anvesh

PoWA semble être un outil intéressant pour PostgreSQL 9.4+. Il recueille des statistiques, les visualise et propose des index. Il utilise le pg_stat_statements extension.

PoWA est PostgreSQL Workload Analyzer qui collecte des statistiques de performances et fournit des tableaux et des graphiques en temps réel pour aider à surveiller et à régler vos serveurs PostgreSQL. Il est similaire à Oracle AWR ou SQL Server MDW.

1
n1000
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 
0
madjardi