Criteri di filtro SQL in criteri di join o clausola where più efficiente
-
05-07-2019 - |
Domanda
Ho una query relativamente semplice che unisce due tabelle. Il & Quot; Dove & Quot; i criteri possono essere espressi nei criteri di join o come clausola where. Mi chiedo quale sia più efficiente.
La query è di trovare le vendite massime per un venditore dall'inizio del tempo fino a quando non sono state promosse.
Caso 1
select salesman.salesmanid, max(sales.quantity)
from salesman
inner join sales on salesman.salesmanid =sales.salesmanid
and sales.salesdate < salesman.promotiondate
group by salesman.salesmanid
Caso 2
select salesman.salesmanid, max(sales.quantity)
from salesman
inner join sales on salesman.salesmanid =sales.salesmanid
where sales.salesdate < salesman.promotiondate
group by salesman.salesmanid
Nota Il caso 1 non ha una clausola where
RDBMS è SQL Server 2005
Modifica Se il secondo pezzo dei criteri di join o la clausola where era sales.salesdate & Lt; una data fissa, quindi non è in realtà alcun criterio di adesione alle due tabelle che cambia la risposta.
Soluzione
Non vorrei usare le prestazioni come fattore decisivo qui - e, onestamente, non penso che ci sia alcuna differenza misurabile nelle prestazioni tra questi due casi, davvero.
Userei sempre il caso n. 2 - perché? Perché a mio avviso, dovresti inserire solo i criteri effettivi che stabiliscono il JOIN tra le due tabelle nella clausola JOIN - tutto il resto appartiene alla clausola WHERE.
Solo una questione di mantenere le cose pulite e mettere le cose a cui appartengono, IMO.
Ovviamente, ci sono casi con JOIN ESTERNI SINISTRO in cui il posizionamento dei criteri fa la differenza in termini di risultati restituiti - quei casi sarebbero ovviamente esclusi dalla mia raccomandazione.
Marc
Altri suggerimenti
Puoi eseguire lo stimatore del piano di esecuzione e il profiler sql per vedere come si sovrappongono.
Tuttavia, sono semanticamente gli stessi sotto il cofano secondo questo MVP di SQL Server:
http://www.eggheadcafe.com/conversation ? & aspx MessageId = 29145383 amp; threadid = 29145379
Preferisco avere dei criteri codificati nel join. Rende l'SQL molto più leggibile e portatile.
Leggibilità: Puoi vedere esattamente quali dati otterrai perché tutti i criteri della tabella sono scritti proprio lì nel join. In dichiarazioni di grandi dimensioni, i criteri possono essere sepolti in altre 50 espressioni ed è facilmente ignorato.
Portabilità: Puoi semplicemente copiare un blocco dalla clausola FROM e incollarlo da qualche altra parte. Ciò fornisce i join e tutti i criteri necessari per seguirlo. Se usi sempre questi criteri quando unisci quelle due tabelle, metterlo nel join è il più logico.
Ad esempio:
FROM
table1 t1
JOIN table2 t2_ABC ON
t1.c1 = t2_ABC.c1 AND
t2_ABC.c2 = 'ABC'
Se è necessario estrarre una seconda colonna dalla tabella 2, è sufficiente copiare quel blocco in Blocco note, cercare / ripetere " ABC " e presto e tutto il nuovo blocco di codice pronto per essere reinserito.
Ulteriori: È anche più semplice cambiare tra un join interno ed esterno senza doversi preoccupare di alcun criterio che possa fluttuare nella clausola WHERE.
Mi riservo rigorosamente la clausola WHERE per i criteri di runtime, ove possibile.
Per quanto riguarda l'efficienza: Se ti riferisci alla velocità di esecuzione, allora come hanno affermato tutti gli altri, è ridondante. Se ti riferisci al debug e al riutilizzo più facili, preferisco l'opzione 1.
Una cosa che voglio dire alla fine quando ho avvisato, prima di quello ... Entrambe le modalità possono offrire le stesse prestazioni o l'utilizzo dei criteri nella clausola Where potrebbe essere leggermente più veloce come indicato in alcune risposte ..
Ma ho identificato una differenza, che puoi usare per le tue esigenze logiche ..
-
L'uso dei criteri nella clausola ON non filtra / salta le righe per selezionare invece le colonne di join sarebbero nulle in base alle condizioni
-
L'uso dei criteri nella clausola Where può filtrare / saltare le righe in tutti i risultati
Non credo che troverai una risposta finita per questo che si applica a tutti i casi. I 2 non sono sempre intercambiabili, poiché per alcune query (alcune join di sinistra) otterrai risultati diversi posizionando i criteri nella riga WHERE vs FROM.
Nel tuo caso, dovresti valutare entrambe queste query. In SSMS, è possibile visualizzare i piani di esecuzione stimati ed effettivi di entrambe queste query: sarebbe un buon primo passo per determinare quale sia più ottimale. Puoi anche visualizzare il tempo & Amp; IO per ciascuno (imposta il tempo di attivazione delle statistiche, imposta le statistiche di attivazione) e ciò ti darà anche informazioni per prendere la tua decisione.
Nel caso delle query nella tua domanda - scommetto che entrambi usciranno con lo stesso piano di query - quindi in questo caso potrebbe non avere importanza, ma in altri potrebbe potenzialmente produrre piani diversi.
Prova questo per vedere la differenza tra 2 ...
SET STATISTICS IO ON
SET STATISTICS TIME ON
select salesman.salesmanid,
max(sales.quantity)
from salesmaninner join sales on salesman.salesmanid =sales.salesmanid
and sales.salesdate < salesman.promotiondate
group by salesman.salesmanid
select salesman.salesmanid,
max(sales.quantity)
from salesmaninner join sales on salesman.salesmanid = sales.salesmanid
where sales.salesdate < salesman.promotiondate
group by salesman.salesmanid
SET STATISTICS TIME OFF
SET STATISTICS IO OFF
Può sembrare irriverente, ma la risposta è la query per la quale l'analizzatore di query produce il piano più efficiente.
A mio avviso, sembrano essere equivalenti, quindi l'analizzatore di query potrebbe produrre piani identici, ma dovresti testarlo.
Nessuno dei due è più efficiente, l'utilizzo del metodo WHERE è considerato il vecchio modo per farlo ( http://msdn.microsoft.com/en-us/library/ms190014.aspx ). Puoi guardare il piano di esecuzione e vedere che fanno la stessa cosa.
Acquisire familiarità con il piano di esecuzione stimato in SQL Management Studio !! Come altri hanno già detto, sei in balia dell'analizzatore, qualunque cosa tu faccia, quindi fidati delle sue stime. Immagino che i due che hai fornito avrebbero prodotto esattamente lo stesso piano.
Se è un tentativo di cambiare una cultura di sviluppo, scegli quella che ti dà un piano migliore; per quelli identici, segui la cultura
L'ho commentato su altri " efficienza " post come questo (è sia sincero che sarcastico) - se è qui che risiedono i tuoi colli di bottiglia, fai il cinque per te e la tua squadra.
Il caso 1 (criteri nel JOIN) è migliore per l'incapsulamento e un maggiore incapsulamento è di solito una buona cosa: diminuzione delle omissioni di copia / incolla in un'altra query, diminuzione dei bug se successivamente convertita in LEFT JOIN e maggiore leggibilità (elementi correlati insieme e meno " noise " nella clausola WHERE). In questo caso, la clausola WHERE acquisisce solo i criteri della tabella principale o criteri che si estendono su più tabelle.