es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Por qué falla el optimizador de consultas cuando coloco una declaración “or” antes de una declaración “in”?

Tengo una consulta relativamente simple que obtiene todas las entradas de historial de un objeto y todos los objetos relacionados. Cuando quiero agregar un ObjectID adicional a los resultados de la búsqueda, el rendimiento es dramáticamente diferente dependiendo de si uso OR o UNION y no entiendo por qué el optimizador no puede simplemente optimizar la versión OR de la consulta.

Esto es lo que hago:

SELECT *
FROM ObjectMain
INNER JOIN ObjectHistory ON ObjectMain.ObjectID = ObjectHistory.ObjectID
WHERE ObjectMain.ObjectID IN
(
SELECT ObjectID FROM RelatedObjects WHERE RelationID =
(SELECT RelationID FROM RelatedObjects WHERE ObjectID = 123)
)

Si ahora quiero agregar ObjectID = 999 a los resultados, puedo hacerlo de dos maneras:

WHERE ObjectMain.ObjectID = 999 OR ObjectMain.ObjectID IN …

O

(SELECT RelationID FROM RelatedObjects WHERE ObjectID = 123) UNION ALL (SELECT 999)

La primera versión tiene un rendimiento pésimo mientras que la segunda tiene un rendimiento normal. La diferencia es de órdenes de magnitud. Dado que este tipo de escenario puede ocurrir con frecuencia, me gustaría entender qué está sucediendo aquí.

PLANES DE EJECUCIÓN:
Exec Plan OR
Exec Plan UNION

Agregué los planes de ejecución. Puedo ver claramente que son diferentes, pero realmente no los entiendo. SQL no es mi experiencia principal y mi experiencia en planes de ejecución es limitada en el mejor de los casos. Principalmente, no entiendo en términos prácticos cómo una consulta tan simple puede tener un rendimiento tan desastroso simplemente porque estoy usando una declaración OR. Son 6448 milisegundos para 664 filas devueltas frente a 60.

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    La razón de la diferencia de rendimiento entre las versiones OR y UNION de la consulta se debe a la forma en que el optimizador de consultas de SQL Server las procesa. Al utilizar OR, el optimizador debe considerar ambas condiciones por separado y luego combinar los resultados. Esto puede resultar en la generación de un plan de ejecución menos eficiente, lo que se traduce en un rendimiento más lento.

    Por otro lado, con UNION, el optimizador puede procesar las dos consultas independientemente y luego combinar los resultados utilizando un operador UNION. Esto puede resultar en la generación de un plan de ejecución más eficiente y un rendimiento más rápido.

    Al analizar los planes de ejecución proporcionados, parece que la versión UNION realiza una búsqueda de índice en la tabla ObjectMain, mientras que la versión OR realiza un escaneo de índice clusterizado. Esto indica que la versión UNION puede utilizar un índice de manera más efectiva, lo que contribuye a su rendimiento más rápido.

    En términos prácticos, es importante considerar el uso de UNION versus OR en consultas con múltiples condiciones. En algunos casos, UNION puede ser una opción más eficiente, mientras que en otros, OR puede ser más apropiado. Además, asegurarse de que existan índices relevantes puede mejorar con frecuencia el rendimiento de la consulta.

Comments are closed.