2010-10-20 11 views
7

ich diesen Absatz in der Oracle-Dokumentation gefundenReihenfolge der Tabellen in Join-Abfrage

, wenn Sie den Namen jeder Abteilung zusammen mit dem Namen seines Manager auswählen möchten, können Sie die Abfrage in schreiben kann man auf zwei Arten. Im ersten Beispiel , die folgt, der Hinweis/++ bestellt ++/ sagt, die Join in der Reihenfolge der Tabellen erscheinen in der FROM-Klausel mit versuchen, die Join-Reihenfolge zu optimieren.

SELECT /*+ordered*/ d.NAME, e.NAME 
FROM DEPT d, EMP e WHERE d.MGR = e.SS# 

oder:

SELECT /*+ordered*/ d.NAME, e.NAME 
FROM EMP e, DEPT d WHERE d.MGR = e.SS# 

Nehmen wir an, es gibt 10 Abteilungen und 1000 Mitarbeiter, und dass die innere Tabelle in jeder Abfrage einen Index für hat die Join-Spalte. In der ersten Abfrage erzeugt die erste Tabelle 10 qualifizierende Zeilen (in diesem Fall die gesamte Tabelle). In der zweiten Abfrage erzeugt die erste Tabelle 1000 qualifizierende Zeilen. Die erste Abfrage greift 10mal auf die EMP-Tabelle zu und durchsucht die DEPT-Tabelle einmal. Die zweite Abfrage scannt die Tabelle EMP einmal, greift jedoch 1000 Mal auf die Tabelle DEPT zu. Daher wird die erste Abfrage viel besser funktionieren. Als eine Faustregel sollten Tabellen von kleinsten effektiven Nummer Zeilen zu größten effektiven Anzahl der Zeilen angeordnet werden. Die effektive Zeilengröße einer Tabelle in einer Abfrage wird durch erhalten, wobei die logischen Bedingungen angewendet werden, die vollständig in dieser Tabelle aufgelöst werden.

Aber ich verstehe das nicht richtig. Wenn es m Zeilen in Tabelle t1 und n Zeilen in Tabelle t2 gibt, würde die SQL-Engine nicht in beiden Fällen m x n Zeilen durchlaufen?

Update: Danke für alle Antworten. Ich werde den Optimierer nicht außer Kraft setzen, wollte nur meinen Gedanken bestätigen.

+2

Können Sie bitte einen Link auf das Dokument veröffentlichen, wo Sie das lesen? –

+0

Sie fehlen die 'WHERE'-Klausel in Ihrer zweiten Abfrage, die in der Oracle-Dokumentation enthalten ist. –

+0

@Peter - Where-Klausel hinzugefügt :) – Jerry

Antwort

2

Das hängt von der WHERE-Anweisung ab.

SELECT /++ordered++/ d.NAME, e.NAME FROM DEPT d, EMP e WHERE d.MGR = e.SS# 

Wird alle Manager für jede Abteilung auswählen. Da 10 Abteilungen vorhanden sind, werden 10 Datensätze abgerufen. Dadurch werden alle Mitarbeiter mit dem Namen der Abteilung in dem sie arbeiten wählen

SELECT /++ordered++/ d.NAME, e.NAME FROM EMP e, DEPT d 

. Da es 1000 Mitarbeiter, Ihre resultset 1000 Zeilen haben.

A JOIN wird niemals den Motor in einer Schleife über m x n Reihen verursachen, du bist resultset einer inneren Verknüpfung wird immer m wenn m < n

+0

Ich verstehe nicht, was Sie meinen "durch resultset eines inneren Joins wird immer m x m wenn m

+0

Ist dies wahr, selbst wenn es keinen Index für die Verbindungsschlüssel gibt? (Wiederum ist dies nur für das Wissen. Ich verstehe, Joins auf Nicht-Indizes wird nicht empfohlen.) – Jerry

+0

@Tony, Es hängt von Ihrer WHERE/ON-Klausel. Im ersten Fall enthält die Ergebnismenge 10 Zeilen, in der zweiten 1000. @Jerry Was meinst du mit Index auf den Verbindungsschlüsseln? – thomaux

4

Nun, im ersten Fall die Anzahl der logischen liest 10 + 10 in der zweiten 1000 + 1000, wobei jede Abteilung durchschnittlich 100 Mal gelesen wurde.

Das Schreiben von Abfragen mit dem ORDERED-Befehl hihn ist jedoch nicht üblich. Es ist am besten, die Optimierung dem Optimierer die meiste Zeit zu überlassen.

Ich bin nicht sicher, genau, welche Dokumentation Sie dieses Zitat erhalten haben, aber wo ich es gesehen habe, geht diesem sehr wichtigen Absatz voraus, den Sie weggelassen haben. Ich zitiere es hier zum Wohle der anderen, die dieses Verfahren zum Schreiben von Abfragen anders denken kann, ist Standard:

Normalerweise Optimierer wählt die besten Ausführungsplan, um eine optimale Reihenfolge der Tabellen verknüpft werden. Falls der Optimierer keinen guten Ausführungsplan erzeugt, können Sie die Ausführungsreihenfolge mit den TIPPS der Funktion SQL steuern. Weitere Informationen finden Sie unter Oracle Database Lite SQL Referenz.

- Oracle® Database Lite Developer's Guide

+2

+1, obwohl ich denke, dass es einen NESTED LOOP JOIN voraussetzt (ein HASH JOIN würde wahrscheinlich gewählt werden, wenn es keine Filterbedingung gibt). Die Tatsache, dass das Dokument eine Nested Loop Join (RULE Optimizer?) Annimmt und die Verwendung von Hints befürwortet, lässt mich denken, dass dieser Rat von einem sehr alten Dokument stammt (Oracle 7?). Wie auch immer, gute Ratschläge, damit der Optimierer seine Arbeit machen kann. –

1

Sie fanden wirklich, dass in Oracle-Dokumentation?

Sie sollten den ORDERED-Hinweis nicht verwenden und Orakel die Entscheidung für Sie treffen lassen - das funktioniert die meiste Zeit heutzutage sehr gut.

Die Join-Reihenfolge macht jedoch einen Leistungsunterschied aus.

Das Beispiel scheint die Nested Loops zu diskutieren beitreten:

Case 1: 
-> 1 lookup to find 10 rows in table A 
-> 10 index lookups in table B 

Case 2: 
-> 1 lookup to find 1000 rows in table B 
-> 1000 index lookups in table A 
Verwandte Themen