2009-09-03 11 views
6

Sto cercando di ottimizzare una query che fa qualcosa di simile:SQLServer Espressioni CASE - valutazione del cortocircuito?

SELECT 
    ... 
    CASE WHEN (condition) THEN (expensive function call #1) 
    ELSE (expensive function call #2) 
    END 
... 

Il piano di query mostra che per anche nei casi in cui il 100% di righe soddisfare la clausola WHEN, una parte sostanziale del tempo è trascorso in chiama al risultato nella sezione ELSE.

L'unico modo in cui posso dare un senso a questo è presumere che SQLServer valuti entrambi i risultati, quindi selezionarne solo uno basato sulla valutazione della condizione WHEN, ma non riesco a trovare alcun riferimento definitivo se i risultati di una dichiarazione CASE vengono valutati prima dei condizionali. Qualcuno può per favore chiarire o indicarmi un riferimento?

+0

Non posso confermarlo affatto, anche quando provo una funzione costosa che richiede una tabella enorme. Se imposto che la prima parte di CASE sia vera al 100% se è il momento, la mia query impiega 5 secondi. In caso contrario, circa 10 minuti. Quale versione di SQL Server? – MartW

risposta

1

È un piano reale o stimato? Sql Server crea piani basati su ciò che si aspetta di fare in base alle statistiche raccolte e ciò non sempre corrisponde a quali condizioni specifiche lo si inviano per un'istanza di un'esecuzione di query.

+0

Oops, ovviamente, questo è tutto. Quando viene eseguita la query effettiva, il piano sembra completamente diverso. Scusa per non aver pensato prima a questo. –

9

SQL è un linguaggio dichiarativo. Esprimi in una query il risultato desiderato e il server è libero di scegliere qualsiasi mezzo per consegnare quei risultati. Pertanto, l'ordine di valutazione di epxressions SQL è non determinato e OR e AND non si verifica un cortocircuito di valutazione.

Tuttavia per CASE La documentazione indica in realtà che il order of evaluation occurs in the order of declaration e la valutazione arresta dopo la prima condizione è soddisfatta:

  • Viene posto input_expression, e poi nell'ordine specificato, valuta input_expression = when_expression per ogni clausola WHEN.

  • Restituisce il result_expression del primo input_expression = when_expression che restituisce TRUE.

Ciò significa che se si vede l'espressione nel ramo FALSE valutato, la sua condizione CASE non è corretto e talvolta FALSE o UNKNOWN. Assicurati che la logica dei tri-valori di SQL sia presa in considerazione (ad esempio, l'account per NULL). Assicurati anche che i dati nelle tabelle siano quelli che ti aspetti (ad esempio, la condizione in realtà valuta FALSE al 100% dei casi).

+0

Non proprio. È stato archiviato un bug in Microsoft Connect, [Aggregates Do not Follow the Semantics Of CASE] (https://connect.microsoft.com/SQLServer/feedback/details/691535/), che ha dimostrato un caso in cui l'ordine di valutazione delle espressioni 'CASE' non è rispettato. Anche la [documentazione MSDN] (http://msdn.microsoft.com/en-us/library/ms181765.aspx) è stata aggiornata: "In alcune situazioni, un'espressione viene valutata prima che un'istruzione CASE riceva i risultati dell'espressione come suo input. " – Douglas

Problemi correlati