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.

È stato utile?

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 ..

  1. 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

  2. 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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top