2013-04-02 7 views
7

Ho cercato di testarlo, ma ho dei dubbi sui miei test dato che i tempi variano molto.Lo spostamento di un vincolo in un'unione è più efficiente della clausola join e where?

-- Scenario 1 
SELECT * FROM Foo f 
    INNER JOIN Bar b ON f.id = b.id 
    WHERE b.flag = true; 

-- Scenario 2 
SELECT * FROM Foo f 
    INNER JOIN Bar b ON b.flag = true AND f.id = b.id; 

Logicamente sembra che lo scenario 2 sarebbe più efficiente, ma io non ero sicuro se il server SQL è abbastanza intelligente per ottimizzare questo o no.

+6

I piani di esecuzione devono essere identici. – MarcinJuraszek

+0

Perché senza la conoscenza del modo in cui SQL interpreta le query, sembra che filtrare il set da unire prima di unirsi sarebbe più efficiente di unire tutto e quindi filtrare. Marcin ha ragione, hanno lo stesso piano di esecuzione. Non avevo familiarità con l'utilizzo di piani di esecuzione - fanno bene il lavoro. –

+0

Probabilmente il titolo dovrebbe essere cambiato per dire esplicitamente "inner join" in quanto è ben accettato che per i join esterni i piani di esecuzione spesso varino. – crokusek

risposta

12

Non sicuro perché pensi che lo scenario 2 "logicamente" sia more efficient. Su un INNER JOIN, tutto è fondamentalmente un filtro, quindi SQL Server può comprimere la logica con la stessa esatta forma del piano sottostante. Ecco un esempio da AdventureWorks2012 (click to enlarge):

enter image description here

ho preferiscono separare il join criteri dai criteri di filtro, quindi sarà sempre scrivere la query nel formato a sinistra. Tuttavia @HLGEM è un buon punto, queste clausole sono intercambiabili in questo caso solo perché è un INNER JOIN. Per un OUTER JOIN, è molto importante posizionare i filtri sul tavolo esterno nei criteri di join, altrimenti si finisce involontariamente con un INNER JOIN e si modifica drasticamente la semantica della query. Quindi il mio consiglio su come il piano può essere collassato vale solo per i join interiori.

Se sei preoccupato per le prestazioni, inizierei con lo sblocco di SELECT * e tirando solo le colonne effettivamente necessarie (e assicurandoti che ci sia un indice di copertura).

Quattro mesi più tardi, è emersa un'altra risposta affermando che di solito ci sarà una differenza nelle prestazioni e che mettere i criteri di filtro nella clausola ON sarà migliore. Mentre non discuterò che è certamente plausibile che ciò possa accadere, ritengo che non sia certamente la norma e non dovrebbe essere qualcosa che usi come scusa per inserire sempre tutti i criteri di filtro nella clausola ON.

+2

Aggiungerò che se si usano i join di sinistra, i set di resust saranno diversi tra l'inserimento della condizione nella join o la clausola where. Quindi fa la differenza lì, ma non tanto nelle prestazioni quanto nei risultati. – HLGEM

+2

@HLGEM si, è vero. Vale anche per i cross join. :-) Ho trattato solo interiore perché è quello che è stato specificamente menzionato nella domanda. Saluti. –

+4

beh, sapevo che lo sapevi, ma così pochi sviluppatori sembrano esserne a conoscenza, ho solo pensato di parlarne in modo che qualcun altro a leggere questa domanda non faccia una supposizione errata per il loro problema. – HLGEM

-5

La risposta accettata è corretta solo per il tuo caso di test.

Una risposta alla domanda del titolo come detto è , spostando il vincolo per la condizione di join può migliorare notevolmente la query e garantisce. Ho visto in forme simili a questo (ma forse non esattamente) ...

select * 
    from A 
inner join B 
    on B.id = a.id 
inner join C 
    on C.id = A.id 
where B.z = 1 and C.z = 2; 

... non ottimizzare per lo stesso piano come il "Join" equivalenti così ho tendono ad usare la "join su" vincoli come best practice anche per i casi più semplici che potrebbero essere risolti in modo ottimale in entrambi i casi.

+6

Invece di assicurarci che ciò accada, puoi fornire la query effettiva con i suoi 2 moduli e i 2 diversi piani prodotti dall'ottimizzatore. Altrimenti, il tuo suggerimento per le migliori pratiche collide con le opinioni degli altri, e tra loro persone come Aaron Bertrand e Paul White che sono ben noti nella comunità SQL Server. –

+4

Mentre è * possibile * che alcuni scenari potrebbero dimostrare diversi percorsi di ottimizzazione a seconda della posizione della clausola! Sospetto che sia estremamente raro! e scriverò la query logicamente (criteri join = ON, criteri filtro = WHERE) a meno che non abbia un motivo di rendimento per indagare sulle alternative. Lo fai sembrare come se la mia dimostrazione sopra sia l'eccezione, eppure la prova migliore che riesci a trovare è "era qualcosa del genere"? Se vuoi che le persone ascoltino le tue affermazioni, ti preghiamo di dimostrare un caso reale in cui ciò che affermi è vero. Altrimenti è solo olio di serpente. –

+0

Sì, dovrei essere in grado di pubblicare qualcosa per eseguire il backup del reclamo. – crokusek

Problemi correlati