5

Tengo una consulta que debe ser dinámica en algunas de las columnas, lo que significa que obtengo un parámetro y de acuerdo con su valor decido qué columna buscar en mi cláusula Where . He aplicado esta solicitud usando la expresión "CASE":Usar "CASE" en la cláusula WHERE para elegir varias columnas daña el rendimiento

(CASE @isArrivalTime WHEN 1 THEN ArrivalTime ELSE PickedupTime END) 
>= DATEADD(mi, [email protected], @sTime) 
AND (CASE @isArrivalTime WHEN 1 THEN ArrivalTime ELSE PickedupTime END) 
< DATEADD(mi, [email protected], @fTime) 

Si @isArrivalTime = 1 después eligió ArrivalTime columna demás eligió PickedupTime columna. Tengo un índice agrupado en ArrivalTime y un índice no agrupado en PickedupTime.

Me he dado cuenta de que cuando estoy usando esta consulta (con @isArrivalTime = 1), mi rendimiento es mucho peor en comparación con solo el uso de ArrivalTime.

Tal vez el optimizador de consultas no puede usar \ elegir el índice correctamente de esta manera?

He comparado los planes de ejecución y he notado que cuando uso el CASE el 32% del tiempo se desperdicia en el escaneo de índice, pero cuando no uso el CASE (just used ArrivalTime`) solo el 3% se desperdicia en este escaneo de índice.

¿Alguien sabe la razón de esto?

Respuesta

0

intenta establecer límites de fecha y hora:

declare @resSTime datetime 
     ,@resFTime datetime 

set @resSTime = DATEADD(mi, [email protected], @sTime) 
set @resFTime = DATEADD(mi, [email protected], @fTime) 

y tratar de cambiar caso a 'o'

(ArrivalTime >= @resSTime 
    and ArrivalTime < @resFTime 
    and @isArrivalTime = 1) 
or (PickedupTime >= @resSTime 
    and PickedupTime < @resFTime 
    and @isArrivalTime <> 1) 
+0

Yap, que resolvió mi problema. ¡Gracias! –

2

La diferencia entre los 2 se debe probablemente a la diferente cantidad de filas que debe escanear. Como su consulta es probable, el resultado final de una combinación entre más tablas. Tenga en cuenta que un escaneo es ... bueno, como dice su nombre, un escaneo de todas las filas. Puede consultar el plan para conocer el número estimado de filas para hacer una idea.

Si usa un filtro en un campo dinámico (por ejemplo, con mayúsculas y minúsculas), el motor no puede usar un índice en ese campo. En un caso como este, es mejor que use sql dinámico para producir el sql correcto que necesita y use exec_sql. O use las declaraciones if para consultar lo correcto directamente.

Puede encontrar este útil para usar sql dinámico, explicará por qué y cómo.

http://www.sommarskog.se/dynamic_sql.html

Cuestiones relacionadas