Analyse der PostgreSQL-Indexnutzung


85

Gibt es ein Tool oder eine Methode, um Postgres zu analysieren und zu bestimmen, welche fehlenden Indizes erstellt und welche nicht verwendeten Indizes entfernt werden sollen? Ich habe ein wenig Erfahrung mit dem "Profiler" -Tool für SQLServer, aber mir ist kein ähnliches Tool bekannt, das in Postgres enthalten ist.


So ist es. Ich habe mir das schon eine Weile nicht mehr angesehen. Meine akzeptierte Antwort wurde aktualisiert.
Cerin

Antworten:


163

Ich mag es, fehlende Indizes zu finden:

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;

Dies prüft, ob mehr Sequenzscans als Indexscans vorhanden sind. Wenn die Tabelle klein ist, wird sie ignoriert, da Postgres Sequenzscans für sie zu bevorzugen scheint.

Die obige Abfrage zeigt fehlende Indizes.

Der nächste Schritt wäre das Erkennen fehlender kombinierter Indizes. Ich denke, das ist nicht einfach, aber machbar. Vielleicht die langsamen Abfragen analysieren ... Ich habe gehört, pg_stat_statements könnte helfen ...


15
Damit dies mit zitierten Bezeichnern funktioniert, ändern Sie die Abfrage in: 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;
Mr. Muskrat

10
Die Ausgabe dieser Abfrage sollte erklärt werden , die Antwort hilfreicher zu machen
cen

Wenn @cen too_much_seqpositiv und groß ist, sollten Sie sich Sorgen machen.
Bergsteiger

Ich habe nur wenige Indizes für eine der Tabellen erstellt, aber diese Abfrage zeigt immer noch die in dieser Tabelle fehlenden Indizes.
Kishore Kumar

1
@KishoreKumar Ich denke, die Statistiken in Postgres enthalten immer noch die Abfragen, die ausgeführt wurden, bevor Sie Ihren Index aktualisiert haben. Abhängig von Ihrem Verkehr sind die Statistiken nach einigen Stunden wieder in Ordnung.
Guettli


10

Auf die Bestimmung fehlender Indizes Ansatz .... Nein. Es gibt jedoch einige Pläne, um dies in zukünftigen Versionen zu vereinfachen, z. B. Pseudoindizes und maschinenlesbare EXPLAIN.

Derzeit müssen Sie EXPLAIN ANALYZEAbfragen mit schlechter Leistung durchführen und dann manuell die beste Route ermitteln. Einige Protokollanalysatoren wie pgFouine können dabei helfen, die Abfragen zu ermitteln.

Bei einem nicht verwendeten Index können Sie Folgendes verwenden, um sie zu identifizieren:

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

Dies hilft dabei, gelesene, gescannte und abgerufene Tupel zu identifizieren.


Frank Heikens weist auch auf einige gute Stellen hin, an denen andere Fragen zur aktuellen Indexnutzung gestellt werden können.
Rfusca

8

Ein weiteres neues und interessantes Tool zur Analyse von PostgreSQL ist PgHero . Es konzentriert sich mehr auf die Optimierung der Datenbank und macht zahlreiche Analysen und Vorschläge.

Bildschirmfoto


6

Sie können die folgende Abfrage verwenden, um die Indexverwendung und die Indexgröße zu ermitteln:

Die Referenz stammt aus diesem 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;

4

Es gibt mehrere Links zu Skripten, mit denen Sie nicht verwendete Indizes im PostgreSQL-Wiki finden können . Die grundlegende Technik besteht darin, pg_stat_user_indexesdiejenigen zu suchen und zu suchen, bei denen idx_scandie Anzahl, wie oft dieser Index zur Beantwortung von Anfragen verwendet wurde, Null oder zumindest sehr niedrig ist. Wenn sich die Anwendung geändert hat und ein früher verwendeter Index wahrscheinlich nicht jetzt vorhanden ist, müssen Sie manchmal ausführen pg_stat_reset(), um alle Statistiken auf 0 zurückzusetzen und dann neue Daten zu sammeln. Sie können die aktuellen Werte für alles speichern und stattdessen ein Delta berechnen, um dies herauszufinden.

Es sind noch keine guten Tools verfügbar, um fehlende Indizes vorzuschlagen. Ein Ansatz besteht darin, die von Ihnen ausgeführten Abfragen zu protokollieren und zu analysieren, welche Abfragen mit einem Abfrageprotokoll-Analysetool wie pgFouine oder pqa lange dauern. Weitere Informationen finden Sie unter " Protokollieren schwieriger Abfragen ".

Der andere Ansatz besteht darin, pg_stat_user_tablesTabellen mit einer großen Anzahl von sequentiellen Scans zu betrachten und zu suchen, bei denen eine große Anzahl vorhanden seq_tup_fetchist. Wenn ein Index verwendet idx_fetch_tupwird, wird stattdessen die Anzahl erhöht. Das kann Sie darauf hinweisen, wenn eine Tabelle nicht gut genug indiziert ist, um Fragen zu beantworten.

Finden Sie heraus, auf welche Spalten Sie dann indizieren sollten? Das führt normalerweise wieder zur Analyse des Abfrageprotokolls zurück.



1

PoWA scheint ein interessantes Tool für PostgreSQL 9.4+ zu sein. Es sammelt Statistiken, visualisiert sie und schlägt Indizes vor. Es verwendet die pg_stat_statementsErweiterung.

PoWA ist PostgreSQL Workload Analyzer, der Leistungsstatistiken sammelt und Echtzeitdiagramme und -grafiken bereitstellt, mit denen Sie Ihre PostgreSQL-Server überwachen und optimieren können. Es ähnelt Oracle AWR oder 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 

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.