2009-01-27 26 views
22

En SQL Server 2005 cuando tengo múltiples parámetros, ¿tengo la garantía de que la orden de evaluación será siempre de izquierda a derecha?Seleccione la orden de evaluación "where clause"

Utilizando un ejemplo:

select a from table where c=1 and d=2

En esta consulta si el "c = 1" condición falla nunca se evaluó la condición "d = 2"?

PD- "c" es una columna entera en un índice, d es un gran varchar y la columna no indexable que requiere un escaneo completo de tabla

actualización yo estaba tratando de evitar la realización de dos consultas o sentencias condicionales, me Solo necesito algo como: si la "condición c" falla, hay una manera de evitar realizar la pesada "condición d", ya que no es necesaria en mi caso.

Respuesta

26

No hay garantías para la orden de evaluación. El optimizador intentará encontrar la forma más eficiente de ejecutar la consulta, utilizando la información disponible.

En su caso, dado que c está indexado y d no, el optimizador debe buscar en el índice todas las filas que coincidan con el predicado en c, luego recuperar esas filas de los datos de la tabla para evaluar el predicado en d .

Sin embargo, si determina que el índice en c no es muy selectivo (aunque no en su ejemplo, una columna de género rara vez se indexa), puede decidir hacer el escaneo de tabla de todos modos.

Para determinar el orden de ejecución, debe obtener un plan de explicación para su consulta. Sin embargo, tenga en cuenta que ese plan puede cambiar dependiendo de lo que el optimizador crea que es la mejor consulta en este momento.

+0

Aunque no estaba explícita en mi pregunta, también estaba en mi mente la cuestión de "buscar columnas no indexadas entre los elementos encontrados en la columna indexada". En mi caso, se adapta perfectamente a mis necesidades, porque consultar la columna indexada primero dejará solo una pequeña cantidad de registros para filtrar, lo cual no es un problema – t3mujin

+1

Solo recuerde mi última frase: el optimizador puede elegir un plan de consulta diferente para cada ejecución . Hay formas de "anclar" planes y también de especificar sugerencias para el optimizador; No estoy familiarizado con cómo funcionan en MS-SQL. – kdgregory

+1

El objetivo de usar un lenguaje declarativo es que el sistema determine el mejor plan de ejecución para usted.Los optimizadores tienden a funcionar bien en este tipo de cosas con las estadísticas actuales; algo llamado "remolinos" puede en teoría funcionar sin estadísticas en absoluto, pero son una invención reciente, y pueden no estar en MS-SQL. – SquareCog

4

SQL Server generará un plan optimizado para cada instrucción que ejecuta. No tiene que pedir su cláusula Where para obtener ese beneficio. La única garuntee que tiene es que va a ejecutar instrucciones en orden para:

SELECT A FROM B WHERE C 
SELECT D FROM E WHERE F 

se ejecutará la primera línea antes de la segunda.

+1

En otras palabras: NO. SQL Server volverá a ordenar sus condiciones en lo que cree que es la forma más rápida. Si las condiciones donde usted tiene efectos secundarios (tal vez a través de llamadas a la función udf) esto podría causar problemas. –

+2

Poner UDF en las cláusulas WHERE puede ser desastrosamente lento. Más o menos tuvimos que proscribirlos, el rendimiento fue muy pobre. – Joe

+0

Esto no es del todo correcto. –

2

Puede ver el plan de ejecución de la consulta y determinar lo que realmente está tratando de hacer. Creo que se supone que el motor de consultas de SQL Server está haciendo este tipo de escaneo y lo traducirá inteligentemente en operaciones. Al igual que, si haces "caro-op Y falso", se evaluará rápidamente como falso.

Por lo que he aprendido, lo que escribe es (y puede ser) diferente de lo que realmente se ejecuta. Simplemente le está diciendo al servidor qué tipo de resultados espera. Cómo se obtiene la respuesta no se correlaciona de izquierda a derecha del código que proporciona.

1

Una forma de controlar el orden de evaluación es con la expresión CASE.

[Editar]

La opinión popular que estaba tratando de expresar era:

Usted no puede depender de orden de evaluación expresión para cosas como “DONDE O”, ya que el optimizador puede elegir un plan que evalúa el segundo predicado antes que el primero. Pero el orden de las expresiones en una sentencia CASE es fijo, , por lo que puede depender de la evaluación determinista de cortocircuitos de una sentencia CASE .

Se pone un poco más complicado que eso, como se explica en el siguiente sitio web:

http://blogs.msdn.com/b/bartd/archive/2011/03/03/don-t-depend-on-expression-short-circuiting-in-t-sql-not-even-with-case.aspx

+1

La página vinculada ha sido eliminada. – Conrad

+1

Gracias @Conrad, actualizó la respuesta de alguna manera –

2

Si usted quiere estar seguro de que puede comprobar la Query Execution Plan. El plan de ejecución que MSSQL crea/optimiza es lo suficientemente inteligente como para verificar la columna indexada antes de una columna varchar.

+1

¿Podemos confiar en esta información al 100%? –

1

El optimizador de consultas de MS SQL Server produce un cortocircuito, sí. Garantizado

Ejecutar este:

select 1 where 1 = 0 and 1/0 = 10 

se ejecutará bien y no de error aunque estás dividiendo por cero porque el optimizador de consultas cortocircuito evaluar la cláusula where. Esto tiene implicaciones para cualquier cláusula where donde estés "y" -ing y una de las partes sea una constante.

+1

Lo siento, no creo que estés en lo correcto. Creo que @kdgregory tiene razón en que no hay garantía aquí. El optimizador de consultas decidirá qué es lo mejor. –

+0

Definitivamente no está garantizado. Estoy lidiando con una situación como esta ahora, donde quiero un cortocircuito para evitar evaluar expresiones cuando ya se conoce el valor de verdad (dada la precedencia habitual del operador), pero eso no está sucediendo. – Conrad

+0

Estas dos partes de la cláusula where son expresiones triviales por lo que el optimizador de consultas no se molesta en reordenarlas. Pruebe este en su lugar: seleccione 1 donde existe (seleccione '¿Alguna fila?' De dbo.LargishTable) y 1/0 = 10 Existen algunos umbrales basados ​​en la forma en que el optimizador de consultas genera planes de ejecución que determinan la orden de evaluación . – Davos

1

El cortocircuito se realiza cuando la condición a la que nos referimos solo incluye literales o constantes. Entonces, por ejemplo, digamos que tenemos una tabla TableA que tiene una columna num con todos los números positivos del 1 al 10 y luego si escribo esta consulta.

Seleccionar num de la Tabla A DONDE TableA.num < 0 Y = 1/0 10.

que dará lugar a error.

¿El compilador es lo suficientemente inteligente como para determinar que mi segunda cláusula consta de constantes, por lo que debería evaluar eso antes de la cláusula de evaluación que requiere cualquier exploración desde la tabla o el índice?

Cuestiones relacionadas