it-swarm.com.de

Zeile "Cond erneut prüfen" in Abfrageplänen mit einem Bitmap-Index-Scan

Dies ist ein Nebeneffekt von Kommentaren zur vorherigen Frage:

Bei Verwendung von PostgreSQL 9.4 scheint es immer ein Recheck Cond: Zeile nach dem Durchsuchen des Bitmap-Index in Abfrageplänen, die von EXPLAIN ausgegeben werden.

Wie in der Ausgabe EXPLAIN der referenzierten Frage:

->  Bitmap Heap Scan on table_three  (cost=2446.92..19686.74 rows=8159 width=7)
      Recheck Cond: (("timestamp" > (now() - '30 days'::interval)) AND (client_id > 0))
      ->  BitmapAnd  (cost=2446.92..2446.92 rows=8159 width=0)
            ->  Bitmap Index Scan on table_one_timestamp_idx  (cost=0.00..1040.00 rows=79941 width=0)
                  Index Cond: ("timestamp" > (now() - '30 days'::interval))
            ->  Bitmap Index Scan on fki_table_three_client_id  (cost=0.00..1406.05 rows=107978 width=0)
                  Index Cond: (client_id > 0)

Oder in der Ausgabe von EXPLAIN ANALYZE für einen einfachen, riesigen Tisch (mit sehr wenig work_mem):

EXPLAIN ANALYZE SELECT * FROM aa WHERE a BETWEEN 100000 AND 200000;
Bitmap Heap Scan on aa  (cost=107.68..4818.05 rows=5000 width=4) (actual time=27.629..213.606 rows=100001 loops=1)
  Recheck Cond: ((a >= 100000) AND (a <= 200000))
  Rows Removed by Index Recheck: 758222
  Heap Blocks: exact=693 lossy=3732
  ->  Bitmap Index Scan on aai  (cost=0.00..106.43 rows=5000 width=0) (actual time=27.265..27.265 rows=100001 loops=1)
        Index Cond: ((a >= 100000) AND (a <= 200000))

Bedeutet das, dass die Indexbedingungen nach einem Bitmap-Index-Scan ein zweites Mal überprüft werden müssen?
Was können wir noch aus der Ausgabe von EXPLAIN lernen?

23

As @ Chris hat die referenzierte Frage richtig kommentiert :

eine kleine Untersuchung scheint darauf hinzudeuten, dass die Bedingung für die erneute Überprüfung immer in EXPLAIN gedruckt wird, aber tatsächlich nur ausgeführt wird, wenn work_mem klein genug ist, dass die Bitmap verlustbehaftet wird. Gedanken? http://www.postgresql.org/message-id/[email protected]

Während dies alles wahr ist und der Kernentwickler Heikki Linnakangas eine erstklassige Quelle ist, stammt der Beitrag aus dem Jahr 2007 (Postgres 8.2). Hier ist ein Blog-Beitrag von Michael Paquier mit ausführlicher Erklärung zu Postgres 9.4 , in dem die Ausgabe von EXPLAIN ANALYZE Mit weiteren Informationen verbessert wurde.

Die Zeile Recheck Cond: Ist immer für Bitmap-Index-Scans. Die Ausgabe von basic EXPLAIN sagt uns nicht mehr. Wir erhalten zusätzliche Informationen von EXPLAIN ANALYZE, Wie aus dem zweiten Zitat in der Frage hervorgeht:

Heap Blocks: exact=693 lossy=3732

Von insgesamt 4425 Datenseiten (Blöcken) wurden 693 Tupel genau (einschließlich Tupelzeiger) gespeichert, während die andere 3732 Seiten waren verlustbehaftet (nur die Datenseite) in der Bitmap. Dies geschieht, wenn work_mem Nicht groß genug ist, um die gesamte aus dem Index-Scan erstellte Bitmap genau zu speichern (verlustfrei).

Die Indexbedingung muss für Seiten aus der verlustbehafteten Freigabe erneut überprüft werden, da sich die Bitmap nur merkt, welche Seiten abgerufen werden sollen, und nicht die genauen Tupel auf der Seite. Nicht alle Tupel auf der Seite bestehen notwendigerweise die Indexbedingungen. Es ist erforderlich, tatsächlich die Bedingung erneut zu überprüfen.

Dies ist der Thread zu pgsql-Hackern, in dem der neue Zusatz besprochen wurde . Der Autor Etsuro Fujita liefert eine Formel zur Berechnung des Minimums work_mem, Um verlustbehaftete Bitmap-Einträge und nachfolgende Bedingungsprüfungen zu vermeiden. Die Berechnung ist für komplexe Fälle mit mehreren Bitmap-Scans nicht zuverlässig, daher wurde sie nicht zur Ausgabe der tatsächlichen Zahlen von EXPLAIN verwendet. Es kann immer noch als Schätzung für einfache Fälle dienen.

Zusätzliche Zeile BUFFERS:

Wenn Sie mit der Option BUFFERS ausführen: EXPLAIN (ANALYZE, BUFFERS) ... wird außerdem eine weitere Zeile hinzugefügt:

Buffers: shared hit=279 read=79

Dies gibt an, wie viel der zugrunde liegenden Tabelle (und des Index) aus dem Cache gelesen wurde (shared hit=279) Und wie viel von der Festplatte abgerufen werden musste (read=79). Wenn Sie die Abfrage wiederholen, verschwindet der Teil "Lesen" normalerweise für nicht zu große Abfragen, da jetzt nach dem ersten Aufruf alles zwischengespeichert wird. Der erste Aufruf zeigt an, wie viel bereits zwischengespeichert wurde. Nachfolgende Aufrufe zeigen, wie viel Ihr Cache (derzeit) verarbeiten kann.

Es gibt mehr Optionen. Das Handbuch zur Option BUFFERS :

Geben Sie insbesondere die Anzahl der gemeinsam genutzten Blöcke an, die getroffen, gelesen, verschmutzt und geschrieben wurden, die Anzahl der lokalen Blöcke, die getroffen, gelesen, verschmutzt und geschrieben wurden, und die Anzahl der gelesenen und geschriebenen temporären Blöcke.

Lesen Sie weiter, es gibt noch mehr.
Hier ist die Liste der Ausgabeoptionen im Quellcode .

18

Erwin, da dies unsere Diskussion im Kommentarthread von früher war, habe ich mich entschlossen, etwas weiter darauf einzugehen ...

Ich habe eine sehr einfache Abfrage von einer Tabelle mit angemessener Größe. Ich habe normalerweise genügend work_mem, Aber in diesem Fall habe ich die Befehle verwendet

SET work_mem = 64;

einen sehr kleinen work_mem und setzen

SET work_mem = default;

um mein work_mem wieder auf ausreichend groß für meine Abfrage zu setzen.

EXPLAIN & Recheck Condition

Führen Sie meine Abfrage also nur mit EXPLAIN as aus

EXPLAIN 
SELECT * FROM olap.reading_facts
WHERE meter < 20;

Ich habe die Ergebnisse für niedrig und hoch erhalten work_mem:

Niedrig work_mem

Bitmap Heap Scan on reading_facts  (cost=898.92..85632.60 rows=47804 width=32)
  Recheck Cond: (meter < 20)
  ->  Bitmap Index Scan on idx_meter_reading_facts  (cost=0.00..886.96 rows=47804 width=0)
        Index Cond: (meter < 20)

Hoch work_mem

Bitmap Heap Scan on reading_facts  (cost=898.92..85632.60 rows=47804 width=32)
  Recheck Cond: (meter < 20)
  ->  Bitmap Index Scan on idx_meter_reading_facts  (cost=0.00..886.96 rows=47804 width=0)
        Index Cond: (meter < 20)

Lange Rede, kurzer Sinn, nur für EXPLAIN, wie erwartet, zeigt der Abfrageplan an, dass eine erneute Überprüfung möglich ist, aber wir können nicht wissen, ob tatsächlich berechnet wird.

ANALYSE ERKLÄREN & Zustand erneut prüfen

Wenn wir ANALYZE in die Abfrage aufnehmen, geben uns die Ergebnisse mehr darüber weiter, was wir wissen müssen.

Niedrig work_mem

Bitmap Heap Scan on reading_facts  (cost=898.92..85632.60 rows=47804 width=32) (actual time=3.130..13.946 rows=51840 loops=1)
  Recheck Cond: (meter < 20)
  Rows Removed by Index Recheck: 86727
  Heap Blocks: exact=598 lossy=836
  ->  Bitmap Index Scan on idx_meter_reading_facts  (cost=0.00..886.96 rows=47804 width=0) (actual time=3.066..3.066 rows=51840 loops=1)
        Index Cond: (meter < 20)

Hoch work_mem

Bitmap Heap Scan on reading_facts  (cost=898.92..85632.60 rows=47804 width=32) (actual time=2.647..7.247 rows=51840 loops=1)
  Recheck Cond: (meter < 20)
  Heap Blocks: exact=1434
  ->  Bitmap Index Scan on idx_meter_reading_facts  (cost=0.00..886.96 rows=47804 width=0) (actual time=2.496..2.496 rows=51840 loops=1)
        Index Cond: (meter < 20)

Wie erwartet enthüllt uns die Aufnahme von ANALYZE wieder einige sehr wichtige Informationen. Im Fall low work_mem Sehen wir, dass durch die erneute Überprüfung des Index Zeilen entfernt wurden und dass wir lossy Heap-Blöcke haben.

Fazit? (oder deren Fehlen)

Leider sieht es so aus, als ob EXPLAIN alleine nicht ausreicht um zu wissen, ob eine Indexüberprüfung tatsächlich durchgeführt wird Dies ist erforderlich, da einige der Zeilen-IDs zugunsten der Beibehaltung von Seiten während des Bitmap-Heap-Scans gelöscht werden.

Die Verwendung von EXPLAIN ANALYZE Ist in Ordnung, um Probleme mit Abfragen mittlerer Länge zu diagnostizieren. Wenn eine Abfrage jedoch extrem lange dauert, führen Sie EXPLAIN ANALYZE Aus, um festzustellen, dass Ihr Bitmap-Index konvertiert wird Verlust aufgrund unzureichender work_mem ist immer noch eine schwierige Einschränkung. Ich wünschte, es gäbe eine Möglichkeit, EXPLAIN die Wahrscheinlichkeit dieses Auftretens anhand der Tabellenstatistik abzuschätzen.

10
Chris