¿Se evalúan las expresiones booleanas en las cláusulas SQL WHERE de cortocircuito ?
Por ejemplo:
SELECT *
FROM Table t
WHERE @key IS NULL OR (@key IS NOT NULL AND @key = t.Key)
Si @key IS NULL se evalúa como verdadero, ¿ @key IS NOT NULL AND @key = t.Key evaluado?
Si no, ¿por qué no?
En caso afirmativo, ¿está garantizado? ¿Forma parte de ANSI SQL o es específico de la base de datos?
Si la base de datos es específica, SqlServer? ¿Oráculo? MySQL?
sql
short-circuiting
Greg Dean
fuente
fuente
WHERE a = 1 AND b = 2
podría ser eficiente para el motor de base de datos encontrar todas las filas donde b = 2 primero, luego filtrar donde a = 1. Si solicita garantía, entonces el optimizador se vuelve inútil.Respuestas:
ANSI SQL Draft 2003 5WD-01-Framework-2003-09.pdf
fuente
CASE
está en cortocircuito.De lo anterior, el cortocircuito no está realmente disponible.
Si lo necesita, le sugiero una declaración de caso:
Expr1
siempre se evalúa, pero solo uno deExpr2
yExpr3
se evaluará por fila.fuente
Creo que este es uno de los casos en que lo escribiría como si no tuviera un cortocircuito, por tres razones.
Porque para MSSQL, no se resuelve mirando BOL en el lugar obvio, por lo que para mí eso lo hace canónicamente ambiguo.
porque al menos sé que mi código funcionará. Y lo que es más importante, también lo harán los que vengan después de mí, así que no los estoy preparando para preocuparse por la misma pregunta una y otra vez.
Escribo con suficiente frecuencia para varios productos DBMS, y no quiero tener que recordar las diferencias si puedo solucionarlos fácilmente.
fuente
No creo que se garantice un cortocircuito en SQL Server (2005). SQL Server ejecuta su consulta a través de su algoritmo de optimización que tiene en cuenta muchas cosas (índices, estadísticas, tamaño de tabla, recursos, etc.) para llegar a un plan de ejecución efectivo. Después de esta evaluación, no puede estar seguro de que su lógica de cortocircuito esté garantizada.
Me encontré con la misma pregunta hace algún tiempo y mi investigación realmente no me dio una respuesta definitiva. Puede escribir una pequeña consulta para darle una prueba de que funciona, pero ¿puede estar seguro de que a medida que aumenta la carga en su base de datos, las tablas crecen y las cosas se optimizan y cambian en la base de datos? sostener. No pude y, por lo tanto, erré por precaución y utilicé la cláusula CASO en DONDE para garantizar un cortocircuito.
fuente
Debe tener en cuenta cómo funcionan las bases de datos. Dada una consulta parametrizada, la base de datos crea un plan de ejecución basado en esa consulta sin los valores para los parámetros. Esta consulta se usa cada vez que se ejecuta, independientemente de los valores reales suministrados. Si los cortocircuitos de consulta con ciertos valores no serán importantes para el plan de ejecución.
fuente
Normalmente uso esto para parámetros opcionales. ¿Es esto lo mismo que cortocircuito?
Esto me da la opción de pasar -1 o lo que sea para tener en cuenta la verificación opcional de un atributo. A veces esto implica unirse en varias tablas, o preferiblemente una vista.
Muy útil, no del todo seguro del trabajo extra que le da al motor db.
fuente
Para SQL Server, creo que depende de la versión, pero mi experiencia con SQL Server 2000 es que todavía evalúa @key = t.Key incluso cuando @key es nulo. En otras palabras, no hace un cortocircuito eficiente al evaluar la cláusula WHERE.
He visto personas que recomiendan una estructura como su ejemplo como una forma de hacer una consulta flexible donde el usuario puede ingresar o no ingresar varios criterios. Mi observación es que Key todavía está involucrado en el plan de consulta cuando @key es nulo y si Key está indexado, entonces no usa el índice de manera eficiente.
Este tipo de consulta flexible con criterios variables es probablemente un caso en el que SQL creado dinámicamente es realmente la mejor manera de hacerlo. Si @key es nulo, simplemente no lo incluya en la consulta.
fuente
Acabo de tropezar con esta pregunta, y ya había encontrado esta entrada de blog: http://rusanu.com/2009/09/13/on-sql-server-boolean-operator-short-circuit/
El servidor SQL es libre de optimizar una consulta en cualquier lugar que le parezca conveniente, por lo que en el ejemplo dado en la publicación del blog, no puede confiar en los cortocircuitos.
Sin embargo, un CASO aparentemente está documentado para evaluarlo en el orden escrito: revise los comentarios de esa publicación de blog.
fuente
La característica principal de la evaluación de cortocircuito es que deja de evaluar la expresión tan pronto como se puede determinar el resultado. Eso significa que el resto de la expresión puede ignorarse porque el resultado será el mismo independientemente de si se evalúa o no.
Los operadores booleanos binarios son conmutativos, lo que significa:
Por lo tanto, no hay garantía en el orden de evaluación. El orden de evaluación será determinado por el optimizador de consultas.
En lenguajes con objetos puede haber situaciones en las que puede escribir expresiones booleanas que solo pueden evaluarse con la evaluación de cortocircuito. La construcción de su código de muestra a menudo se usa en dichos lenguajes (C #, Delphi, VB). Por ejemplo:
Este ejemplo de C # causará una excepción si
someString == null
se evaluará completamente. En la evaluación de cortocircuito, funcionará siempre.SQL opera solo en variables escalares (sin objetos) que no se pueden inicializar, por lo que no hay forma de escribir expresiones booleanas que no se puedan evaluar. Si tiene algún valor NULL, cualquier comparación devolverá falso.
Eso significa que en SQL no puede escribir expresiones que se evalúen de manera diferente dependiendo del uso de cortocircuito o evaluación completa.
Si la implementación de SQL utiliza la evaluación de cortocircuito, solo puede acelerar la ejecución de consultas.
fuente
No sé sobre el cortocircuito, pero lo escribiría como una declaración if-else
Además, las variables siempre deben estar en el lado derecho de la ecuación. Esto lo hace sargable.
http://en.wikipedia.org/wiki/Sargable
fuente
Debajo de una prueba rápida y sucia en SQL Server 2008 R2:
Esto vuelve inmediatamente sin registros. El tipo de comportamiento de cortocircuito estaba presente.
Entonces probé esto:
sabiendo que ningún registro satisfaría esta condición:
Esto tomó varios segundos, lo que indica que el comportamiento del cortocircuito ya no existía y que la operación compleja se estaba evaluando para cada registro.
Espero que esto ayude a los chicos.
fuente
Aquí hay una demostración para demostrar que MySQL realiza un cortocircuito en la cláusula WHERE :
http://rextester.com/GVE4880
Esto ejecuta las siguientes consultas:
La única diferencia entre estos es el orden de los operandos en la condición OR.
myslowfunction
duerme deliberadamente por un segundo y tiene el efecto secundario de agregar una entrada a una tabla de registro cada vez que se ejecuta. Estos son los resultados de lo que se registra al ejecutar las dos consultas anteriores:Lo anterior muestra que una función lenta se ejecuta más veces cuando aparece en el lado izquierdo de una condición OR cuando el otro operando no siempre es verdadero (debido a un cortocircuito).
fuente
Esto toma 4 segundos adicionales en el analizador de consultas, por lo que puedo ver si IF ni siquiera está en corto ...
¡Sería bueno tener una forma garantizada!
fuente
Es obvio que el servidor MS Sql admite la teoría de cortocircuito para mejorar el rendimiento al evitar verificaciones innecesarias,
Ejemplo de apoyo:
Aquí, el primer ejemplo daría como resultado el error 'Error de conversión al convertir el valor varchar' A 'al tipo de datos int'.
Mientras que el segundo se ejecuta fácilmente ya que la condición 1 = 1 se evaluó como VERDADERA y, por lo tanto, la segunda condición no se ejecutó en absoluto.
Además
aquí la primera condición se evaluaría como falsa y, por lo tanto, el DBMS pasaría a la segunda condición y nuevamente obtendrá el error de conversión como en el ejemplo anterior.
NOTA: ESCRIBÍ LA CONDICIÓN ERRÓNEA SOLO PARA REALIZAR EL CLIMA LA CONDICIÓN SE EJECUTA O SE CORTA CORTOCIRCUITO SI LA CONSULTA RESULTA POR ERROR SIGNIFICA QUE LA CONDICIÓN SE EJECUTÓ, CORTOCIRCUITO DE OTRA MANERA.
EXPLICACIÓN SIMPLE
Considerar,
ya que la primera condición se evalúa como VERDADERA , no tiene sentido evaluar la segunda condición porque su evaluación en cualquier valor no afectaría el resultado en absoluto, por lo que es una buena oportunidad para que SQL Server ahorre tiempo de ejecución de consultas omitiendo la comprobación o evaluación de condiciones innecesarias .
en el caso de "OR" si la primera condición se evalúa como VERDADERA, toda la cadena conectada por "OR" se consideraría evaluada como verdadera sin evaluar otras.
Si la condición1 se evalúa como verdadera, descanse todas las condiciones hasta que se salte la condiciónN. En palabras generalizadas en la determinación del primer VERDADERO , se omitirán todas las demás condiciones vinculadas por OR.
Considera la segunda condición
ya que la primera condición se evalúa como FALSA evalúa como tiene sentido evaluar la segunda condición porque su evaluación en cualquier valor no afectaría el resultado en absoluto, por lo que nuevamente es una buena oportunidad para que Sql Server ahorre tiempo de ejecución de consultas omitiendo la comprobación o evaluación de condiciones innecesarias .
en caso de "Y" si la primera condición se evalúa como FALSA, toda la cadena conectada con el "Y" se consideraría evaluada como FALSA sin evaluar otras.
si la condición1 se evalúa como FALSA , descanse todas las condiciones hasta que se salte la condiciónN . En palabras generalizadas en la determinación del primer FALSO , se omitirán todas las demás condiciones vinculadas por AND .
POR LO TANTO, UN PROGRAMADOR SABIO DEBE SIEMPRE PROGRAMAR LA CADENA DE CONDICIONES DE TAL MANERA QUE, CONDICION MENOS GASTA O MÁS ELIMINADORA SE EVALUE PRIMERO, O ARREGLAR LA CONDICIÓN DE TAL MANERA QUE PUEDA TENER UN MÁXIMO BENEFICIO DE CORTO CIRCUITO
fuente