PostgreSQL-Abfragen noch benutzerfreundlicher verstehen

Vor sechs Monaten haben wir vorgestellt explain.tensor.ru — einen öffentlichen Dienst zur Analyse und Visualisierung von Abfrageplänen für PostgreSQL.

PostgreSQL-Abfragen noch benutzerfreundlicher verstehen

In den vergangenen Monaten haben wir darüber auf der PGConf.Russia 2020 einen Bericht, einen zusammenfassenden Artikel zur Beschleunigung von SQL-Abfragen auf der Grundlage der Empfehlungen, die er liefert… aber das Wichtigste ist, dass wir Ihr Feedback gesammelt und die realen Anwendungsfälle verfolgt haben.

Und jetzt sind wir bereit, über die neuen Möglichkeiten zu berichten, die Sie nutzen können.

Unterstützung verschiedener Planformatierungen

Plan aus dem Log, zusammen mit der Anfrage

Markieren Sie direkt aus der Konsole den gesamten Block, beginnend mit der Zeile mit Query Text, mit allen führenden Leerzeichen:

        Query Text: INSERT INTO dicquery_20200604 VALUES ($1.*) ON CONFLICT (query)
                           DO NOTHING;
        Insert on dicquery_20200604 (cost=0.00..0.05 rows=1 width=52) (actual time=40.376..40.376 rows=0 loops=1)
          Conflict Resolution: NOTHING
          Conflict Arbiter Indexes: dicquery_20200604_pkey
          Tuples Inserted: 1
          Conflicting Tuples: 0
          Buffers: shared hit=9 read=1 dirtied=1
          -> Result (cost=0.00..0.05 rows=1 width=52) (actual time=0.001..0.001 rows=1 loops=1)

… und fügen alles kopierte direkt ins Planfeld ein, ohne es zu trennen:

PostgreSQL-Abfragen noch benutzerfreundlicher verstehen

Am Ende erhalten wir zusätzlich zum zerlegten Plan auch einen Tab „Kontext“, in dem unsere Anfrage in vollem Umfang dargestellt ist:

PostgreSQL-Abfragen noch benutzerfreundlicher verstehen

JSON und YAML

EXPLAIN (ANALYZE, BUFFERS, FORMAT JSON)
SELECT * FROM pg_class;

"[
  {
    "Plan": {
      "Node Type": "Seq Scan",
      "Parallel Aware": false,
      "Relation Name": "pg_class",
      "Alias": "pg_class",
      "Startup Cost": 0.00,
      "Total Cost": 1336.20,
      "Plan Rows": 13804,
      "Plan Width": 539,
      "Actual Startup Time": 0.006,
      "Actual Total Time": 1.838,
      "Actual Rows": 10266,
      "Actual Loops": 1,
      "Shared Hit Blocks": 646,
      "Shared Read Blocks": 0,
      "Shared Dirtied Blocks": 0,
      "Shared Written Blocks": 0,
      "Local Hit Blocks": 0,
      "Local Read Blocks": 0,
      "Local Dirtied Blocks": 0,
      "Local Written Blocks": 0,
      "Temp Read Blocks": 0,
      "Temp Written Blocks": 0
    },
    "Planning Time": 5.135,
    "Triggers": [
    ],
    "Execution Time": 2.389
  }
]"

Ob mit äußeren Anführungszeichen, wie pgAdmin es kopiert, oder ohne — werfen wir es in dasselbe Feld, am Ende — eine Schönheit:

PostgreSQL-Abfragen noch benutzerfreundlicher verstehen

Erweiterte Visualisierung

Planungszeit / Ausführungszeit

Jetzt ist besser zu erkennen, wo die zusätzliche Zeit bei der Ausführung der Abfrage geblieben ist:

PostgreSQL-Abfragen noch benutzerfreundlicher verstehen

I/O-Zeitmessung

Manchmal findet man sich in der Situation wieder, dass im Plan zwar nicht allzu viele Ressourcen gelesen oder geschrieben werden, aber die Ausführungszeit irgendwie unangemessen hoch ist.

Hier muss gesagt werden: "Oh, wahrscheinlich war die Festplatte auf dem Server in diesem Moment zu stark belastet, daher hat das Lesen so lange gedauert!" Aber das ist nicht besonders präzise…

Aber man kann das absolut zuverlässig feststellen. Denn unter den Konfigurationsoptionen des PG-Servers gibt es track_io_timing:

Beinhaltet die Messung der Ein-/Ausgabezeiten. Diese Option ist standardmäßig deaktiviert, da es erforderlich ist, die aktuelle Zeit ständig vom Betriebssystem abzufragen, was die Leistung auf einigen Plattformen erheblich verlangsamen kann. Um die Kosten der Zeitmessung auf Ihrer Plattform zu bewerten, können Sie das Tool pg_test_timing verwenden. Statistiken zur Ein-/Ausgabe können über die Ansicht pg_stat_database abgerufen werden, im EXPLAIN-Ausgabe (wenn die Option BUFFERS verwendet wird), und über die Ansicht pg_stat_statements.

Diese Option kann auch in einer lokalen Sitzung aktiviert werden:

SET track_io_timing = TRUE;

Jetzt kommt das Beste: Wir haben gelernt, diese Daten zu verstehen und darzustellen, wobei wir alle Transformationen des Ausführungsbaums berücksichtigen:

PostgreSQL-Abfragen noch benutzerfreundlicher verstehen

Hier kann man sehen, dass von 0,790 ms Gesamtausführungszeit 0,718 ms für das Lesen einer Datenseite benötig wurden, 0,044 ms für das Schreiben derselben, und für alle anderen nützlichen Aktivitäten wurden insgesamt nur 0,028 ms aufgewendet!

Die Zukunft mit PostgreSQL 13

Eine vollständige Übersicht der Neuerungen finden Sie in einem ausführlichen Artikel, und wir konzentrieren uns speziell auf die Änderungen in den Plänen.

Planungs-Buffer

Die Ressourcenzuteilung für den Planner fand ihren Ausdruck in einem weiteren Patch, der nicht zu pg_stat_statements gehört. EXPLAIN mit der Option BUFFERS wird die Anzahl der während der Planungsphase verwendeten Puffer melden:

 Seq Scan auf pg_class (tatsächliche Zeilen=386 Schleifen=1)
   Puffer: gemeinsamer Treffer=9 gelesen=4
 Planungszeit: 0,782 ms
   Puffer: gemeinsamer Treffer=103 gelesen=11
 Ausführungszeit: 0,219 ms

PostgreSQL-Abfragen noch benutzerfreundlicher verstehen

Inkrementelle Sortierung

In Fällen, in denen eine Sortierung nach mehreren Schlüsseln (k1, k2, k3…) erforderlich ist, kann der Planner jetzt das Wissen nutzen, dass die Daten bereits nach mehreren der ersten Schlüssel (z. B. k1 und k2) sortiert sind. In diesem Fall muss nicht mehr alles neu sortiert werden, sondern die Daten können in aufeinanderfolgende Gruppen mit gleichen Werten für k1 und k2 unterteilt und nach dem Schlüssel k3 "nachsortiert" werden.

Somit zerfällt die gesamte Sortierung in mehrere aufeinanderfolgende Sortierungen kleinerer Größe. Dies reduziert den benötigten Speicherbedarf und ermöglicht es zudem, die ersten Daten früher auszugeben, bevor die gesamte Sortierung vollständig ausgeführt wurde.

 Inkrementelle Sortierung (tatsächliche Zeilen=2.949.857 Schleifen=1)
   Sortierschlüssel: ticket_no, passenger_id
   Vorgeordneter Schlüssel: ticket_no
   Vollsortiergruppen: 92.184 Sortiermethode: Quicksort Speicher: avg=31kB peak=31kB
   ->  Index-Scan mit tickets_pkey auf tickets (tatsächliche Zeilen=2.949.857 Schleifen=1)
 Planungszeit: 2,137 ms
 Ausführungszeit: 2230,019 ms

PostgreSQL-Abfragen noch benutzerfreundlicher verstehen
PostgreSQL-Abfragen noch benutzerfreundlicher verstehen

UI/UX Verbesserungen

Screenshots, sie sind überall!

Jetzt gibt es auf jeder Registerkarte die Möglichkeit, schnell einen Screenshot der Registerkarte in die Zwischenablage in voller Breite und Tiefe der Registerkarte — "Ziel" rechts oben:

PostgreSQL-Abfragen noch benutzerfreundlicher verstehen

Tatsächlich wurden die meisten Bilder für diese Veröffentlichung genau so erhalten.

Empfehlungen zu den Knoten

Es gibt nicht nur mehr, sondern man kann auch zu jedem detaillierte Informationen im Artikel nachlesen, indem Sie dem Link folgen:

PostgreSQL-Abfragen noch benutzerfreundlicher verstehen

Löschen aus dem Archiv

Einige haben dringend gebeten, die Möglichkeit hinzuzufügen, es "vollständig" zu löschen, sogar nicht veröffentlichte Pläne im Archiv — bitte, ein einfaches Klicken auf das entsprechende Symbol genügt:

PostgreSQL-Abfragen noch benutzerfreundlicher verstehen

Nun, und vergessen wir nicht, dass wir eine Support-Gruppe haben,, an die man seine Anmerkungen und Vorschläge senden kann.

Quelle: habr.com

Zuverlässiges Webhosting mit DDoS-Schutz, VPS- und VDS-Server kaufen 🔥 Zuverlässiges Webhosting mit DDoS-Schutz, VPS- und VDS-Server kaufen | ProHoster