2009-05-12 6 views
3

Gibt es beim Zusammenfügen von Tabellen (wie in den folgenden Beispielen) einen Effizienzunterschied zwischen dem Verknüpfen von Tabellen oder dem Verknüpfen von Unterabfragen, die nur die erforderlichen Spalten enthalten?Tabelle Join Efficiency Frage

Mit anderen Worten, gibt es einen Unterschied in der Effizienz zwischen diesen beiden Tabellen?

SELECT result 
    FROM result_tbl 
    JOIN test_tbl     USING (test_id) 
    JOIN sample_tbl     USING (sample_id) 
    JOIN (SELECT request_id 
      FROM request_tbl 
     WHERE request_status='A') USING(request_id) 

vs

SELECT result 
    FROM (SELECT result, test_id FROM result_tbl) 
    JOIN (SELECT test_id, sample_id FROM test_tbl) USING(test_id) 
    JOIN (SELECT sample_id   FROM sample_tbl) USING(sample_id) 
    JOIN (SELECT request_id 
      FROM request_tbl 
     WHERE request_status='A')     USING(request_id) 
+0

Schöne Frage - Ich werde jemand mehr kenntnisreiche Antwort geben, aber meine Ahnung ist, dass die beiden in Bezug auf Effizienz etwa gleich sind, da die DB-Engine in beiden Fällen auf die gleiche Anzahl von Spalten verbinden muss und daher aussehen in der gleichen Anzahl von Zeilen (obwohl weniger Felder beteiligt sind). Korrigiere mich, wenn ich falsch liege! – AndreiM

+0

Mark Brady hätte diese Frage LIEBT, aber nooooo .... Die Eliten hier in der Nähe haben ihn mit ihrer Machtmache verscheucht. – TheSoftwareJedi

+0

Schließen Sie diese Frage als nicht mehr relevant, da jeder weiß, dass SQL Server besser ist und wir nicht einmal fragen müssen. – TheSoftwareJedi

Antwort

4

Es spielt keine Rolle. Es kann tatsächlich schlechter sein, da Sie die Kontrolle weg von dem Optimierer nehmen, der im Allgemeinen am besten weiß.

Aber denken Sie daran, wenn Sie ein JOIN machen und nur eine Spalte aus einer der Tabellen, die es besser ist, es als eine Reihe von EXISTS-Anweisungen neu zu schreiben - denn das ist, was Sie wirklich meinen. JOINs (mit einigen Ausnahmen) verbinden übereinstimmende Zeilen, was für den Optimierer viel mehr Arbeit bedeutet.

z.B.

SELECT t1.id1 
    FROM table1 t1 
INNER JOIN table2 ON something = something 

fast immer sollte

SELECT id1 
    FROM table1 t1 
WHERE EXISTS(SELECT * 
       FROM table2 
       WHERE something = something) 

Für einfache Abfragen werden das Optimierungsprogramm die Abfragepläne in identische verringern kann. Überprüfen Sie es in Ihrem DBMS.

Auch dies ist ein Code Geruch und wahrscheinlich geändert werden sollte:

JOIN (SELECT request_id VON request_tbl WHERE REQUEST_STATUS = 'A')

zu

SELECT result 
    FROM request 
WHERE EXISTS(...) 
    AND request_status = 'A' 
5

Der einzige Weg, Um sicher zu gehen, sollten Sie beide mit aktivierter Ablaufverfolgung ausführen und sich dann die Ablaufverfolgungsdatei ansehen. Aber wahrscheinlich werden sie gleich behandelt: Der Optimierer wird alle Inline-Ansichten in die Hauptaussage zusammenführen und den gleichen Abfrageplan erstellen.

2

Kein Unterschied.

Sie können sagen, indem Sie EXPLAIN PLAN auf beiden Aussagen ausführen - Oracle weiß, dass alles, was Sie wollen, ist die Spalte "Ergebnis", so dass es nur das Minimum benötigt, um die Daten zu erhalten - Sie sollten die Pläne finden identisch sein. Der Oracle-Optimierer "materialisiert" manchmal eine Unterabfrage (dh führt die Unterabfrage aus und speichert die Ergebnisse zur späteren Wiederverwendung im Speicher), dies ist jedoch selten und tritt nur auf, wenn der Optimierer der Ansicht ist, dass dies zu einer Leistungsverbesserung führt ; In jedem Fall führt Oracle diese "Materialisierung" durch, unabhängig davon, ob Sie die Spalten in den Unterabfragen angegeben haben oder nicht.

Wenn die Spalte "results" nur in den Blöcken gespeichert ist (zusammen mit den übrigen Daten), muss Oracle diese Blöcke natürlich besuchen - aber es werden nur die relevanten Informationen (das "Ergebnis") gespeichert. Spalte und andere relevante Spalten, zB "test_id") im Speicher bei der Verarbeitung der Abfrage.