it-swarm.it

Operatori logici OR AND nelle condizioni e nell'ordine delle condizioni in WHERE

Esaminiamo queste due affermazioni:

IF (CONDITION 1) OR (CONDITION 2)
...

IF (CONDITION 3) AND (CONDITION 4)
...

Se CONDITION 1 è TRUE, sarà CONDITION 2 essere controllato?
Se CONDITION 3 è FALSE, sarà CONDITION 4 essere controllato?

Che dire delle condizioni su WHERE: il motore SQL Server ottimizza tutte le condizioni in una clausola WHERE? I programmatori dovrebbero inserire le condizioni nell'ordine giusto per essere sicuri che l'ottimizzatore di SQL Server lo risolva nel giusto modo?

AGGIUNTO:

Grazie a Jack per il collegamento, sorpresa dal codice t-sql:

IF  1/0 = 1 OR 1 = 1
      SELECT 'True' AS result
ELSE
      SELECT 'False' AS result


IF  1/0 = 1 AND 1 = 0
      SELECT 'True' AS result
ELSE
      SELECT 'False' AS result

In questo caso non viene sollevata un'eccezione Dividi per zero .

conclusione

Se C++/C #/VB presenta un corto circuito, perché non è possibile che SQL Server ce l'abbia?

Per rispondere veramente a questo, diamo un'occhiata a come entrambi funzionano con le condizioni. C++/C #/VB hanno tutti un corto circuito definito nelle specifiche della lingua per accelerare l'esecuzione del codice. Perché preoccuparsi di valutare N OR condizioni quando il primo è già vero o M AND condizioni quando il primo è già falso.

Come sviluppatori, dobbiamo essere consapevoli del fatto che SQL Server funziona in modo diverso. È un sistema basato sui costi. Per ottenere il piano di esecuzione ottimale per la nostra query, il processore di query deve valutare ogni condizione e assegnargli un costo. Questi costi vengono quindi valutati nel loro insieme per formare una soglia che deve essere inferiore alla soglia definita che SQL Server ha per un buon piano. Se il costo è inferiore alla soglia definita, viene utilizzato il piano, in caso contrario l'intero processo viene ripetuto nuovamente con una diversa combinazione di costi di condizione. Il costo qui è una scansione o una ricerca o un join unione o un hash join ecc ... Per questo motivo il corto circuito come è disponibile in C++/C #/VB semplicemente non è possibile. Potresti pensare che forzare l'uso dell'indice su una colonna sia considerato un corto circuito, ma non è così. Impone solo l'uso di quell'indice e con ciò accorcia l'elenco dei possibili piani di esecuzione. Il sistema è ancora basato sui costi.

Come sviluppatore devi essere consapevole che SQL Server non esegue i cortocircuiti come avviene in altri linguaggi di programmazione e non c'è niente che puoi fare per forzarlo.

35
garik

Non esiste alcuna garanzia in SQL Server se o in quale ordine le istruzioni verranno elaborate in una clausola WHERE. La singola espressione che consente il cortocircuito delle istruzioni è CASE-WHEN. Quanto segue proviene da una risposta che ho pubblicato su Stackoverflow:

In che modo SQL Server esegue il cortocircuito della valutazione delle condizioni DOVE

Lo fa quando ne hai voglia, ma non nel modo in cui pensi immediatamente.

Come sviluppatore devi essere consapevole che SQL Server non esegue il corto circuito come avviene in altri linguaggi di programmazione e non c'è niente che tu possa fare per forzarlo .

Per ulteriori dettagli, controlla il primo link nel precedente post sul blog, che sta conducendo a un altro blog:

Cortocircuito di SQL Server?

Il verdetto finale? Bene, non ne ho ancora uno, ma è probabilmente sicuro affermare che l'unica volta in cui puoi assicurarti un cortocircuito specifico è quando esprimi più condizioni QUANDO in un'espressione CASE . Con le espressioni booleane standard, l'ottimizzatore sposta le cose come meglio crede in base alle tabelle, agli indici e ai dati che stai interrogando.

27
MicSim

SQL è un linguaggio di programmazione dichiarativo . Diversamente, diciamo, C++ che è un linguaggio di programmazione imperativo .

Cioè puoi dirlo cosa vuoi nel risultato finale, ma non puoi dettare come il risultato viene eseguito, dipende tutto dal motore.

L'unico vero modo per garantire un flusso di controllo "cortocircuito" (o qualsiasi altro ) all'interno di WHERE è utilizzare viste indicizzate, temporanee tabelle e meccanismi simili.

PS. Puoi anche usare i suggerimenti del piano di esecuzione (per "suggerire" al motore come eseguire una query, quali indici usare e COME usarli), ho pensato che avrei dovuto menzionarlo, mentre siamo su questo argomento ...

0
jitbit