Operadores lógicos OR Y en condición y orden de condiciones en DONDE

33

Examinemos estas dos declaraciones:

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

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

Si CONDITION 1es así TRUE, ¿ CONDITION 2será verificado?
Si CONDITION 3es así FALSE, ¿ CONDITION 4será verificado?

¿Qué pasa con las condiciones en WHERE: el motor de SQL Server optimiza todas las condiciones en una WHEREcláusula? ¿Deberían los programadores colocar las condiciones en el orden correcto para asegurarse de que el optimizador de SQL Server lo resuelva de la manera correcta ?

ADICIONAL:

Gracias a Jack por el enlace, sorpresa del código 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

No hay una excepción Divide por cero en este caso.

CONCLUSIÓN:

Si C ++ / C # / VB tiene un cortocircuito, ¿por qué SQL Server no puede tenerlo?

Para responder realmente a esto, echemos un vistazo a cómo ambos trabajan con condiciones. C ++ / C # / VB tienen cortocircuito definido en las especificaciones del lenguaje para acelerar la ejecución del código. ¿Por qué molestarse en evaluar las condiciones N O cuando la primera ya es verdadera o las condiciones M AND cuando la primera ya es falsa?

Como desarrolladores, debemos ser conscientes de que SQL Server funciona de manera diferente. Es un sistema basado en costos. Para obtener el plan de ejecución óptimo para nuestra consulta, el procesador de consultas debe evaluar cada condición where y asignarle un costo. Estos costos se evalúan en su conjunto para formar un umbral que debe ser inferior al umbral definido que SQL Server tiene para un buen plan. Si el costo es más bajo que el umbral definido, se usa el plan, si no, todo el proceso se repite nuevamente con una combinación diferente de costos de condición. El costo aquí es un escaneo o una búsqueda o una combinación de fusión o una combinación hash, etc. ... Debido a esto, el cortocircuito como está disponible en C ++ / C # / VB simplemente no es posible. Puede pensar que forzar el uso del índice en una columna cuenta como cortocircuito, pero no es así. Solo fuerza el uso de ese índice y con eso acorta la lista de posibles planes de ejecución. El sistema todavía está basado en costos.

Como desarrollador, debe tener en cuenta que SQL Server no hace un cortocircuito como se hace en otros lenguajes de programación y no hay nada que pueda hacer para forzarlo.

Garik
fuente
¿De dónde es el bloque de presupuesto final? ¿Podría agregar una referencia?
Nick Chammas

Respuestas:

25

No hay garantía en SQL Server si o en qué orden se procesarán las declaraciones en una WHEREcláusula. La única expresión que permite el cortocircuito de sentencias es CASE- WHEN. Lo siguiente es de una respuesta que publiqué en Stackoverflow:

Cómo SQL Server cortocircuita DONDE evaluación de condición

Lo hace cuando le da la gana, pero no de la forma en que piensa de inmediato.

Como desarrollador, debe tener en cuenta que SQL Server no hace un cortocircuito como se hace en otros lenguajes de programación y no hay nada que pueda hacer para forzarlo .

Para obtener más detalles, consulte el primer enlace en la entrada de blog anterior, que conduce a otro blog:

¿Cortocircuito SQL Server?

El veredicto final? Bueno, todavía no tengo uno, pero probablemente sea seguro decir que el único momento en que puede garantizar un cortocircuito específico es cuando expresa múltiples condiciones WHEN en una expresión CASE. Con expresiones booleanas estándar, el optimizador moverá las cosas como mejor le parezca en función de las tablas, índices y datos que está consultando.

MicSim
fuente
2
Al parecer hay algunos casos de borde (o un error), donde aún case no es seguro
Jack Douglas
1
También demuestro otro caso (¡ja!) Donde se CASErompe: dba.stackexchange.com/questions/12941/…
Aaron Bertrand
0

SQL es un lenguaje de programación declarativo . A diferencia de, digamos, C ++, que es un lenguaje de programación imperativo .

Es decir, puede decirle lo que desea en el resultado final, pero no puede dictar cómo se ejecuta el resultado, todo depende del motor.

La única forma verdadera de garantizar el "cortocircuito" (o cualquier otro flujo de control ) en el interior WHEREes mediante el uso de vistas indexadas, tablas temporales y mecanismos similares.

PD. También puede usar sugerencias de planes de ejecución (para "insinuar" al motor cómo ejecutar una consulta, qué índices usar y CÓMO usarlos), solo pensé que debería mencionarlo, mientras estamos en este tema ...

jitbit
fuente
-4

1) - O (cualquiera o ambas condiciones serán VERDADERAS)

si la condición 1 es VERDADERA, entonces la condición 2 también se verificará, puede ser VERDADERO o FALSO

--Y (ambas condiciones deben ser VERDADERAS)

si la condición 1 es FALSA, entonces la condición 2 no se verificará

Ranjith Kumar
fuente
"si la condición 1 es FALSA, entonces la condición 2 no se verificará" Esto no es cierto. Ver la respuesta anterior . SQL Server aún puede evaluar la condición 2 porque no realiza una evaluación de cortocircuito en las WHEREcláusulas.
Nick Chammas
-4

La única forma de controlar cómo las condiciones dentro de la cláusula WHERE es usar corchetes para agruparlos.

WHERE Col1 = 'Something' AND Col2 = 'Something' OR Col3 = 'Something' and Col4 = 'Something'

es muy diferente de

WHERE (Col1 = 'Something' AND Col2 = 'Something') OR (Col3 = 'Something' and Col4 = 'Something')
mrdenny
fuente
Sólo curioso. ¿Cómo son diferentes estas dos condiciones? Diferentes resultados, rendimiento, plan de ejecución? Pensé que serían equivalentes.
ypercubeᵀᴹ
Con el primero, debe hacer coincidir Col1, Col4 y Col2 o Col3. En la segunda línea para hacer coincidir Col1 y Col2 o necesita hacer coincidir Col3 y Col4, pero Col1 y Col4 nunca necesitarán ser evaluados juntos.
mrdenny 01 de
1
No, estás equivocado. ANDtiene mayor prioridad que OR. Ambos son equivalentes. Lo que diga sería cierto para la WHERE Col1 = x AND (Col2 = x OR Col3 = x) AND Col4 = xconsulta. Ver prueba SQL-Fiddle
ypercubeᵀᴹ