2016-12-08 1 views
0

Ich habe eine Abfrage, die eine lange Zeit zur Ausführung dauert. Ich habe ungefähr 10 Minuten gewartet und es ist immer noch nicht fertig ausgeführt.Beschleunigen einer Abfrage mit INNER JOIN

Die Abfrage sieht wie folgt aus:

SELECT 
    one.ID, 
    two.NAME, 
    two.STATUS, 
    four.KEY, 
    four.VALUE, 
    count(one.ID) as num 
FROM TABLE_ONE one, TABLE_TWO two, TABLE_THREE three, TABLE_FOUR four 
WHERE one.STATE='RED' 
    AND (two.STATUS='ON' OR two.STATUS='OFF') 
    AND (
    four.KEY='FINAL' 
    OR four.KEY='LIMIT' 
    OR (
     four.KEY='MODE' 
     AND (
     four.VALUE='T' 
     OR four.VALUE='R'))) 
GROUP BY one.ID, two.NAME, two.STATUS, four.KEY, four.VALUE 
ORDER BY group_name ASC; 

Ich habe noch eine Abfrage, die äquivalent ist aber führt sehr schnell (etwa 1 Sekunde auszuführen). Hier

ist diese Abfrage:

SELECT 
    one.ID, 
    two.NAME, 
    two.STATUS, 
    four.KEY, 
    four.VALUE, 
    count(one.ID) as num 
FROM TABLE_ONE one 
INNER JOIN TABLE_TWO two 
ON one.ID=two.ID 
INNER JOIN TABLE_THREE three 
ON two.ID=three.GROUP_ID 
INNER JOIN TABLE_FOUR four 
ON three.ID=four.ID 
WHERE one.STATE='RED' 
    AND (two.STATUS='ON' OR two.STATUS='OFF') 
    AND (
    four.KEY='FINAL' 
    OR four.KEY='LIMIT' 
    OR (
     four.KEY='MODE' 
     AND (
     four.VALUE='T' 
     OR four.VALUE='R'))) 
GROUP BY one.ID, two.NAME, two.STATUS, four.KEY, four.VALUE 
ORDER BY group_name ASC; 

Ich bin ein bisschen verwirrt, warum die Abfrage mit INNER JOIN wirklich schnell ausführt (ca. 1 Sekunde) und die man ohne eine lange Zeit in Anspruch nimmt (warteten ca. 10 Minuten und noch nicht fertig ausgeführt).

Gibt es irgendetwas, was ich mit der Abfrage ohne INNER JOIN tun kann, um die Ausführungszeit zu beschleunigen?

Ich verwende ORACLE.

+0

Sie sollten sich den Ausführungsplan ansehen (oder "Plan erklären"). Meine Vermutung ist, dass die 'Inner Join'-Version Indizes verwendet, um die Leistung zu erhöhen, während die Version mit den Join-Kriterien zusammen mit Filterkriterien aus irgendeinem Grund keine Indizes verwendet. Oder ein anderer Unterschied, der offensichtlich sein sollte, wenn Sie den Ausführungsplan betrachten. – SlimsGhost

Antwort

2

In der ersten Abfrage sind die Tabellen in keiner Spalte wirklich verbunden. Das Ergebnis heißt cross join. Der Kreuz-Join zwischen zwei Tabellen-Zeilen entspricht der Anzahl der Zeilen in der ersten Tabelle und der Anzahl der Zeilen in der zweiten Tabelle.

Inner join Joins basierend auf dem angegebenen Satz von Spalten.

0

Ihre lang laufende Abfrage hat keine Join-Bedingungen, um eine Tabelle mit der anderen in Beziehung zu setzen. Daher erstellt es ein kartesisches Produkt aller Datensätze in jeder Tabelle. Wenn also jede Tabelle 10 Zeilen hat, würde sie 10 * 10 * 10 * 10 = 10.000 Ergebniszeilen generieren, bevor die Aggregatfunktionen ausgeführt werden. Größere Tabellen werden nur schlechter. Wenn jeder Tisch 1.000 Zeilen hätte, würden Sie am Ende 1.000.000.000.000 Zeilen generieren.

Ihre schnellere Abfrage hat Verknüpfungskriterien, die die Anzahl der Zeilen in der Ergebnismenge erheblich reduzieren, weshalb sie leistungsfähiger ist.

0

Sagen wir, Sie haben N Werte für ID. In der ersten Abfrage erstellen Sie N * N * N * N (oder N^4) Zeilen.

In der zweiten werden Sie N Zeilen erstellen.

In O-Notation:

O(N^4) 

vs

O(N) 

Jetzt haben Sie eine reale Welt Beispiel für die Auswirkungen.