0

Ich habe festgestellt, dass Postgres keinen Index für eine Bereichsabfrage in einer partitionierten Tabelle verwendet.Postgres verwendet keinen Index für Bereichsabfrage in partitionierter Tabelle

Die Eltern-Tabelle und ihre Partitionen werden mit ihrer Datumsspalte über btree indiziert.

Eine Abfrage wie folgt aus:

select * from parent_table where date >= '2015-07-01'; 

keine Indizes verwenden.

EXPLAIN Ergebnis:

Append (cost=0.00..106557.52 rows=3263963 width=128) 
-> Seq Scan on parent_table (cost=0.00..0.00 rows=1 width=640) 
    Filter: (date >= '2015-07-01'::date) 
-> Seq Scan on z_partition_2015_07 (cost=0.00..106546.02 rows=3263922 width=128) 
    Filter: (date >= '2015-07-01'::date) 
-> Seq Scan on z_partition_2015_08 (cost=0.00..11.50 rows=40 width=640) 
    Filter: (date >= '2015-07-01'::date) 

Aber eine Abfrage wie folgt:

select * from parent_table where date = '2015-07-01' 

verwendet einen Index.

EXPLAIN Ergebnis:

Append (cost=0.00..30400.95 rows=107602 width=128) 
-> Seq Scan on parent_table (cost=0.00..0.00 rows=1 width=640) 
    Filter: (date = '2015-07-01'::date) 
-> Index Scan using z_partition_2015_07_date on z_partition_2015_07 (cost=0.43..30400.95 rows=107601 width=128) 
    Index Cond: (date = '2015-07-01'::date) 

Wenn ich die Abfrage auf einem anderen normalen Tisch mit date indiziert laufen, beide Abfragen verwenden Sie den Index.

Gibt es etwas Besonderes, dass wir auf partitionierte Tabelle Index tun sollten?

+0

versuchen, das Datum zwischen der Bedingung –

+0

zu verwenden. Zeigen Sie die EXPLAIN-Analysepläne für beide an. –

+0

Schwer zu sagen, ohne über die Größe Ihrer Daten und deren Struktur zu wissen. Versuchen Sie zunächst 'VACUUM ANALYSE parent_table', um Statistiken zu Ihrer partitionierten Tabelle zu sammeln. Wenn es nicht half, versuchen Sie es in psql 'SET enable_seqscan = off 'und wiederholen Sie Ihre Abfrage. Der Planer sollte den Index-Scan verwenden, damit Sie die Kosten von seqscan und indexscan vergleichen können. Wahrscheinlich ist Seqscan einfach billiger für diese Art von Abfrage.Indexscan ist nicht sehr gut bei großen Datenmengen abgerufen werden. –

Antwort

0

Ich nehme an, Sie wissen, dass "Partitionen" sind separate Tabellen in Postgres. Indizes sind normalerweise nicht verwendet, wenn große Teile einer Tabelle (mehr als ~ 5%, es hängt von vielen Details) ab, da es in solchen Fällen in der Regel schneller ist, nur die Tabelle sequenziell zu scannen.

Was mehr ist, scheint es, als ob Sie alle Zeilen von den beteiligten Partitionen in Ihrer ersten Abfrage auswählen. Keine Verwendung für Indizes ...

Im Allgemeinen ist ein Gleichheitsprädikat mit = ist mehr selektive als ein Prädikat mit >= .Think darüber:

Ihre erste Abfrage mit date >= '2015-07-01' ruft alle Zeilen von der Trennwand (Raten, ich müsste die genaue Definition sehen). Die Verwendung des Index würde nur Overhead-Kosten hinzufügen. Aber Ihre zweite Abfrage mit date = '2015-07-01' holt nur einen kleinen Prozentsatz. Postgres erwartet eine Indexsuche schneller.

0

vielleicht ist das nur so schneller? Führen Sie Ihre Abfrage, dann tun Sie dies:

SET enable_seqscan=false 

Und es erneut ausführen.

Verwandte Themen