2016-12-11 4 views
2

Ich habe die Notwendigkeit, eine riesige Tabelle (10 Millionen plus Zeilen) zu einer Nachschlagetabelle (15k plus Zeilen) mit einer ODER-Bedingung zu verbinden. Etwas wie:Redshift - effiziente JOIN-Klausel mit OR

SELECT t1.a, t1.b, nvl(t1.c, t2.c), nvl(t1.d, t2.d) 
FROM table1 t1 
JOIN table2 t2 ON t1.c = t2.c OR t1.d = t2.d; 

Dies liegt daran, tabelle1 c oder d als NULL haben kann, und ich möchte auf welcher auch immer beizutreten zur Verfügung steht, den Rest Weglassen. Der Abfrageplan sagt, dass es eine verschachtelte Schleife gibt, die ich wegen der Bedingung OR realisiere. Gibt es eine saubere und effiziente Lösung dieses Problems? Ich benutze Redshift.

EDIT: Ich versuche, dies mit einem UNION auszuführen, aber es scheint nicht schneller als zuvor zu sein.

+0

Können Sie den Abfrageplan freigeben? – greginvm

+0

Stellen Sie sicher, dass Sie "union all" für Fälle verwenden, in denen Duplikate kein Problem darstellen, da sie viel schneller sind. – systemjack

Antwort

0

Wenn Sie eine bevorzugte Spalte haben, können Sie NVL() (aka COALESCE()) ihnen und beitreten.

SELECT t1.a, t1.b, nvl(t1.c, t2.c), nvl(t1.d, t2.d) 
FROM table1 t1 
JOIN table2 t2 
    ON t1.c = NVL(t2.c,t2.d); 

Ich würde auch vorschlagen, dass Sie die Lookup-Tabelle auf DISTSTYLE ALL setzen sollen, um sicherzustellen, dass die größere Tabelle nicht neu verteilt wird.

[Auch 10 Millionen Zeilen sind nicht groß für Redshift. Ich versuche nicht rotzig zu sein, wenn ich sage, dass wir eine hervorragende Leistung bei Redshift erzielen, selbst wenn wir Tabellen mit Hunderten von Milliarden Zeilen abfragen (und verbinden). ]

0

Wie wäre es mit zwei (linken) Joins? Mit der kleinen Nachschlagetabelle sollte die Leistung selbst nicht zu schlecht sein.

SELECT t1.a, t1.b, nvl(t1.c, t2.c), nvl(t1.d, t3.d) 
FROM table1 t1 
LEFT JOIN table2 t2 ON t1.d = t2.d and t1.c is null 
LEFT JOIN table2 t3 ON t1.c = t3.c and t1.d is null 

Ihre ursprüngliche Abfrage gibt nur Zeilen zurück, die mindestens eins von c oder d in der Nachschlagetabelle entsprechen. Wenn das nicht garantiert ist, müssen Sie möglicherweise Filter hinzufügen ... zum Beispiel Zeilen in t1, in denen sowohl c als auch d null sind oder Werte haben, die in table2 nicht vorhanden sind.

Sie brauchen die Null-Checks in den Joins nicht wirklich, können aber etwas schneller sein.