2009-05-18 11 views
9

Se eseguo la seguente query SQLSQL delle operazioni

SELECT * 
FROM A 
LEFT JOIN B 
ON A.foo=B.foo 
WHERE A.date = "Yesterday" 

Se la presa WHERE ottenere valutata prima o dopo la JOIN?

Se dopo, quale sarebbe un modo migliore per scrivere questa istruzione in modo che vengano restituite solo le righe in A da "Yesterday" a B?

+0

'quello che sarebbe un modo migliore di scrivere questa dichiarazione in modo che solo le righe in A da "Yesterday" sono uniti a B.' (risposta tardiva) -> 'INNER JOIN' –

risposta

8

Dipende dal database.

Su SQL Server, eseguire: SET SHOWPLAN_ALL ON quindi eseguire la query, si otterrà un'idea di cosa succede quando viene eseguito.

1

Dipende da indici e statistiche.

È necessario mostrare il percorso di esecuzione della query per determinare dove applicare eventuali ottimizzazioni.

5

Semanticamente: dopo il JOIN. Ma in questo caso, non c'è differenza nel tempo, perché è sul lato SINISTRA del JOIN.

Come già fatto, "solo le righe in A da" Ieri "sono unite a B".

L'ottimizzatore è libero di riorganizzare l'ordine delle operazioni in base alle equivalenze dell'algebra relazionale.

Questo restituisce solo A.date = "Yesterday" e si unisce B dove può trovare una partita in foo:

SELECT * FROM A 
LEFT JOIN B 
    ON A.foo=B.foo 
WHERE A.date="Yesterday" 

Ciò restituisce tutti gli A prescindere da qualsiasi criterio e si unisce B dove A.date =" Ieri "E trova una corrispondenza su foo:

SELECT * FROM A 
LEFT JOIN B 
    ON A.foo=B.foo 
    AND A.date="Yesterday" 
+0

Giusto per capire, stai dicendo che mettere i criteri nella clausola WHERE è meglio dal punto di vista delle prestazioni che metterlo nella clausola JOIN? – NotMe

+0

Non fa alcuna differenza per le prestazioni su INNER JOIN ed è per questo che l'ottimizzatore ha più opzioni per spostare le cose intorno a JOIN INNER. In un OUTER JOIN (LEFT o RIGHT), influisce sulla semantica della dichiarazione, quindi le prestazioni non sono di solito il problema. –

7

La tua idea di" valutazione "non è corretta in quanto SQL è un linguaggio dichiarativo.

BTW è possibile visualizzare il piano di esecuzione della query. In MySQL prefisso la tua query con la parola chiave describe per vedere il piano di esecuzione.

2

L'ordine delle operazioni per soddisfare una query è determinato perché il capriccio del query optimizer del database specifico. Un ottimizzatore di query tenta di produrre un buon "piano di query" (serie di operazioni) in base a ciò che può ricavare dalla query e qualsiasi statistica abbia a disposizione sul database (che potrebbe includere la cardinalità delle tabelle e alcune distribuzioni di dati) .

Nel tuo caso, la risposta può dipendere dal fatto che si dispone di un indice secondario su A.date

ottimizzazione delle query abbastanza ricco argomento. La documentazione per qualsiasi database che stai usando avrà molto altro da dire al riguardo.

1

in SQL Server:

Come regola generale di pollice, JOIN clausole vengono valutate prima clausole WHERE.

In caso di complesso si unisce a quella dei filtri necessità nella parte unirsi, li scrivo insieme con la mia unirsi

SELECT * 
FROM A 
LEFT JOIN B 
    ON A.Foo1 = B.Foo1 
    And A.Date = 'Yesterday' 
OUTER JOIN C 
    ON B.Foo2 = C.Foo2 
JOIN D 
    ON B.Foo3 = D.Foo3 
+0

Questo non ha lo stesso significato quando lo si utilizza all'interno di SINISTRA. Nel LEFT JOIN, quando i criteri non sono soddisfatti, le righe LEFT vengono ancora restituite e tutte le colonne da destra sono NULL. –

+0

Sono corretto sull'esempio fornito. Stavo cercando di mettere il punto di mettere la parte di una clausola insieme al join appropriato. Ho corretto la dichiarazione. –

+0

:) sono in piedi ricollegato .. NON POSSO correggere la dichiarazione. –

0
SELECT * 
FROM (SELECT * FROM A WHERE Date = 'Yesterday') A 
LEFT JOIN B 
    ON A.Foo1 = B.Foo1 
OUTER JOIN C 
    ON B.Foo2 = C.Foo2 
JOIN D 
    ON B.Foo3 = D.Foo3