von Markus Winand.

PostgreSQL Zugriffs- und Filterprädikate unter­schei­den


Die PostgreSQL Datenbank kann where-Bedingungen (Prädikate) auf drei verschiedene Arten anwenden:

Zugriffsprädikat („Index Cond“)

Die Zugriffsprädikate bestimmen den Anfangs- und End-Punkt beim Verfolgen der Blattknote-Liste.

Index-Filterprädikat („Index Cond“)

Index-Filterprädikate werden während des Durchsuchens der Blatt­kno­ten-Liste angewandt. Sie haben aber keinen Einfluss auf die Start- und Stopp-Bedingungen und grenzen den durchsuchten Indexbereich nicht ein.

Filterprädikat auf Tabellenebene („Filter“)

Prädikate, die sich auf Spalten beziehen, die nicht im Index sind, können erst auf Tabellenebene berücksichtigt werden. Dafür muss zuerst ein Tabellenzugriff durchgeführt werden.

Beachte

Bei einem PostgreSQL-Ausführungsplan kann man nicht zwischen Index-Zugriffs- und -Filter-Prädikaten unterschieden – beide werden als „Index Cond“ bezeichnet. Das bedeutet, dass man den Ausführungsplan mit der Indexdefinition vergleichen muss, um die Zugriffs- und Index-Filterprädikate zu unterscheiden.

Die als Filter gekennzeichneten Prädikate eines PostgreSQL-Aus­füh­rungs­planes beziehen sich immer auf den Tabellenzugriff. Da sie unter anderem bei der Index Scan-Operation angezeigt werden, können sie leicht als Index-Filterprädikate missverstanden werden.

Hinweis in eigener Sache

Ich biete SQL Schulungen, Optimierung und Beratung an. Auch der Kauf meines Buches „SQL Performance Explained“ (ab €9,95) unterstützt meine Arbeit an dieser Webseite.

Das Beispiel aus dem Kapitel „Performance und Skalierbarkeit“ verdeutlicht es (create & insert Skripte):

CREATE TABLE scale_data (
   section NUMERIC NOT NULL,
   id1     NUMERIC NOT NULL,
   id2     NUMERIC NOT NULL
)
CREATE INDEX scale_data_key ON scale_data(section, id1)

Die folgende Abfrage sucht mit der ID2-Spalte, die jedoch nicht im Index enthalten ist:

PREPARE stmt(int) AS SELECT count(*) 
                       FROM scale_data
                      WHERE section = 1
                        AND id2 = $1
EXPLAIN EXECUTE stmt(1)

Die Bedingung mit der ID2-Spalte scheint als Filter unter der Operation Index Scan auf. Das liegt dran, dass die PostgreSQL Datenbank den Tabellen­zu­griff als Teil der Index Scan-Operation durchführt. Anders ausgedrückt ist die Oracle-Operation TABLE ACCESS BY INDEX ROWID bei PostgreSQL in der Index Scan-Operation versteckt. Daher können bei der Operation Index Scan Filterprädikate für Spalten auftauchen, die nicht im Index sind.

Wichtig

Filter-Prädikate sind bei PostgreSQL immer Tabellenfilter – selbst wenn sie bei der Operation Index Scan aufscheinen.

Legt man den Index aus dem Abschnitt Auswirkungen des Datenvolumens an, sieht man auch, dass sowohl Zugriffs- als auch Index-Filterprädikate als „Index Cond“ aufscheinen:

DEALLOCATE stmt

Der Ausführungsplan nutzt den Index, zeigt jedoch keine Filter-Information mehr an:

                      QUERY PLAN
------------------------------------------------------
Aggregate  (cost=14215.98..14215.99 rows=1 width=0)
  Output: count(*)
  -> Index Scan using scale_slow on scale_data 
     (cost=0.00..14208.51 rows=2989 width=0)
     Index Cond: (section = 1::numeric AND id2 = ($1)::numeric)

Die Bedingung auf der Spalte ID2 kann den durchsuchten Indexbereich nicht eingrenzen, da die Spalte ID1 vor ID2 im Index ist. Das bedeutet, dass der Index Scan den gesamten Bereich der Bedingung SECTION=1::numeric liest und den Filter ID2=($1)::numeric auf jede Zeile anwendet. Diese Bedingung ist also ein Index-Filterprädikat, das im Ausführungsplan nicht gesondert gekennzeichnet wird.

Tipp

Vorherige SeiteNächste Seite

Du kannst nicht alles an einem Tag lernen. Abonniere den Newsletter via E-Mail, Twitter oder RSS um sukzessive aufzuholen. Und sieh dir auch modern-sql.com an.

Über den Autor

Foto von Markus Winand

Markus Winand gibt auf modern-sql.com Einblick in SQL und zeigt, wie es von verschiedenen Systemen unterstützt wird. Zuvor machte er use-the-index-luke.com, was er noch immer wartet. Markus kann als Trainer, Sprecher und Berater auf winand.at engagiert werden.

Sein Buch kaufen

Titelbild von „SQL Performance Explained“: Eichhörnchen läuft durchs Grass

Die Essenz: SQL-Tuning auf 200 Seiten

Jetzt Kaufen
(Taschenbuch und/oder PDF)

Sein Training

Markus verwandelt veraltetes SQL-92-Wissen in solides und zeitgemäßes SQL-Know-how

Erfahren Sie mehr»

Mit Markus Winand verbinden

Markus Winand auf LinkedInMarkus Winand auf XINGMarkus Winand auf Twitter
„Use The Index, Luke!“ von Markus Winand ist unter einer Creative Commons Attribution-Noncommercial-No Derivative Works 3.0 Unported License lizenziert.
Impressum | Kontakt | KEINE GEWÄHR | Handelsmarken | Datenschutz und DSGVO | CC-BY-NC-ND 3.0 Lizenz