Sehr schlechte Leistung von UNION select-Abfrage in der Rotverschiebung / ParAccel
Ich habe zwei Tabellen in einer Rotverschiebung:
- tbl_current_day - etwa 4,5 M Zeilen
- tbl_previous_day - etwa 4,5 M Zeilen, mit den gleichen Daten genau so, wie tbl_current_day
Neben es, ich habe eine Ansicht mit der Bezeichnung qry_both_days wie folgt definiert:
CREATE OR REPLACE qry_both_days AS
SELECT * FROM tbl_current_day
UNION SELECT * FROM tbl_previous_day;
Wenn ich eine Abfrage ausführen, auf einem der separaten Tische, ich bekomme sehr gute Leistung, wie erwartet.
Zum Beispiel die folgende Abfrage ausgeführt wird 5 Sekunden:
select count(distinct person_id) from tbl_current_day;
-- (person_id is of type int)
Erklären, plan:
XN Aggregate (cost=1224379.82..1224379.82 rows=1 width=4)
-> XN Subquery Scan volt_dt_0 (cost=1224373.80..1224378.61 rows=481 width=4)
-> XN HashAggregate (cost=1224373.80..1224373.80 rows=481 width=4)
-> XN Seq Scan on tbl_current_day (cost=0.00..979499.04 rows=97949904 width=4)
Beachten Sie, dass die Breite von 4 Byte, wie es sein soll, wie meine Spalte ist vom Typ int.
JEDOCH, wenn ich den gleichen query auf qry_both_days die Abfrage ausgeführt, die 20 mal langsamer, während ich würde erwarten, dass es laufen nur 2 mal langsamer, als es sollte gehen über zweimal mehr Zeilen:
select count(distinct person_id) from qry_both_days;
Erklären, plan:
XN Aggregate (cost=55648338.34..55648338.34 rows=1 width=4)
-> XN Subquery Scan volt_dt_0 (cost=55648335.84..55648337.84 rows=200 width=4)
-> XN HashAggregate (cost=55648335.84..55648335.84 rows=200 width=4)
-> XN Subquery Scan qry_both_days (cost=0.00..54354188.49 rows=517658938 width=4)
-> XN Unique (cost=0.00..49177599.11 rows=517658938 width=190)
-> XN Append (cost=0.00..10353178.76 rows=517658938 width=190)
-> XN Subquery Scan "*SELECT* 1" (cost=0.00..89649.20 rows=4482460 width=190)
-> XN Seq Scan on tbl_current_day (cost=0.00..44824.60 rows=4482460 width=190)
-> XN Subquery Scan "*SELECT* 2" (cost=0.00..90675.00 rows=4533750 width=187)
-> XN Seq Scan on tbl_previous_day (cost=0.00..45337.50 rows=4533750 width=187)
Das problem: Breite ist jetzt 190, nicht mit 4 bytes, wie es sein soll!!!
Jeder weiß, wie man die Rotverschiebung picken sich nur die relevanten Spalten auf UNION WÄHLEN?
Dank!
- Da die Daten in der früheren und aktuellen Tag-Tabellen sollten disjunkt, Sie sollten in der Lage sein, um eine zusätzliche performance-Steigerung durch Verwendung von UNION-ALLE, die überspringen den DEUTLICHEN Schritt der UNION-operation.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ihrer Ansicht erstellt, wie
SELECT *
, so dass es immer alle Abfragen die Spalten zu erstellen, die Daten für die Ansicht.Dann noch
SELECT
verwendet wird und nur die angeforderten Spalten aus der view zurückgegeben.Wenn Sie haben begrenzte Anzahl von ausgewählten Spalten (wie ein zwei, drei Sätze, die die ganze Zeit benutzt), würde ich erstellen Sie eine eigene Ansicht für jede Spalte festlegen.
Anderen (auch weniger elegant als eine Ehe) ist zu nennen, jede Ansicht, so sein name sagt, die Spalten enthalten sind (sagen wir sortiert und getrennt mit '__') - wie
qry_both_days__age__name__person_id
. Dann jeweils vor der Abfrage prüfen, ob der gewünschte Sicht existiert, wenn nicht erstellen Sie es.UNION
von selbst entfernt doppelte Zeilen, z.B., verwendet eine impliziteDISTINCT
gemäß SQL-spec.Dass bedeutet, dass viel mehr Verarbeitung erforderlich ist zur Vorbereitung der Ausgabe.
Wenn Sie nicht möchten, dass
DISTINCT
Ergebnisse, dann sollten Sie immer verwendenUNION ALL
um sicherzustellen, dass die Datenbank nicht die überprüfung für potenzielle dupes.SELECT * [..] UNION SELECT [..]
undSELECT * [..] UNION ALL SELECT * [..]
ist ziemlich stark.UNION ALL
ist etwa 5% teurer ist, als ein single-tableSELECT
, währendUNION
ist ungefähr 150x so teuer. Hier ist eine Zusammenfassung mit den kommentiertenEXPLAIN
Ausgabe - gist.github.com/slpsys/5e43d8237fd8aa924015