Pregunta

Estoy tratando de optimizar algunas consultas SQL terriblemente complicado porque se tarda demasiado tiempo a fin.

En mis consultas, he creado dinámicamente las sentencias SQL con una gran cantidad de las mismas funciones, así que creé una tabla temporal, donde cada función sólo se llama una vez en lugar de muchas, muchas veces - este corte mi tiempo de ejecución por 3/4.

Así que mi pregunta es, ¿puedo esperar a ver mucha diferencia si digamos, 1.000 cálculos DateDiff se redujo a 100?

EDIT: Las miradas consulta como la siguiente:

SELECT DISTINCT M.MID, M.RE FROM #TEMP INNER JOIN M ON #TEMP.MID=M.MID 
WHERE ( #TEMP.Property1=1 ) AND 
DATEDIFF( year, M.DOB, @date2 ) >= 15  AND  DATEDIFF( year, M.DOB, @date2 ) <= 17 

cuando éstos están siendo generados dinámicamente como cadenas (ponen juntos en trozos y piezas) y luego ejecutadas de modo que diferentes parámetros se pueden cambiar a lo largo de cada iteración -. Principalmente las últimas líneas, que contiene todo tipo de consultas DATEDIFF

Hay alrededor de 420 consultas de este tipo, donde estos datediffs se calculan como tal. Sé que puedo tirar a todos en una tabla temporal con facilidad (1.000 datediffs convierte 50) - pero ¿vale la pena, va a hacer ninguna diferencia en cuestión de segundos? Estoy esperando una mejora mejor que en las décimas de segundo.

¿Fue útil?

Solución

Depende exactamente lo que está haciendo para ser honesto en cuanto a la magnitud de la pérdida de rendimiento.

Por ejemplo, si está utilizando DATEDIFF (o de hecho cualquier otra función) dentro de una cláusula WHERE, entonces esto va a ser una causa de un peor rendimiento ya que evitará que un índice que se utiliza en esa columna.

por ejemplo. ejemplo básico, la búsqueda de todos los registros en 2009

WHERE DATEDIFF(yyyy, DateColumn, '2009-01-01') = 0

No sería hacer un buen uso de un índice en DateColumn. Mientras que una solución mejor, que proporciona el uso de índices óptima sería:

WHERE DateColumn >= '2009-01-01' AND DateColumn < '2010-01-01'

recientemente escribió en su blog acerca la diferencia que esto hace (con estadísticas de rendimiento / Comparación de los planes de ejecución), si está interesado.

Eso sería más costoso que digamos regresar DATEDIFF como una columna en el conjunto de resultados.

Me sería empezar por identificar las consultas individuales que se están llevando la mayor parte del tiempo. Comprobar los planes de ejecución para ver dónde se encuentra el problema y sintonizar a partir de ahí.

Editar Sobre la base de la consulta de ejemplo que has dado, aquí es un enfoque que podría probar para eliminar el uso de DATEDIFF dentro de la cláusula WHERE. Básico ejemplo, para encontrar todos los que tenía 10 años en una fecha determinada - I que las matemáticas es correcto, pero se entiende la idea de todos modos! Nos dio una prueba rápida, y parece bien. Debería ser bastante fácil de adaptar a su escenario. Si usted quiere encontrar personas entre (por ejemplo) 15 y 17 años de edad en una fecha determinada, entonces eso también es posible con este enfoque.

-- Assuming @Date2 is set to the date at which you want to calculate someone's age 
DECLARE @AgeAtDate INTEGER
SET @AgeAtDate = 10  

DECLARE @BornFrom DATETIME
DECLARE @BornUntil DATETIME
SELECT @BornFrom = DATEADD(yyyy, -(@AgeAtDate + 1), @Date2)
SELECT @BornUntil = DATEADD(yyyy, -@AgeAtDate , @Date2)

SELECT DOB
FROM YourTable
WHERE DOB > @BornFrom AND DOB <= @BornUntil

Una nota importante añadir, es para caculates edad de DOB, este método es más preciso. Su implementación actual sólo toma el año de nacimiento en cuenta, no el día real (a alguien, por ejemplo, nacido el 1 Dic 2009 sería mostrar como 1 año de edad del 1 Ene 2010, cuando no lo son 1 hasta el 1 dic 2010).

Espero que esto ayude.

Otros consejos

DATEDIFF es bastante eficiente en comparación con otros métodos de manipulación de fecha y hora valores, como cuerdas. ( ver este SO respuesta ) .

En este caso, parece que usted va una y otra vez los mismos datos, lo que probablemente más caro que utilizar una tabla temporal. Por ejemplo, se generarán estadísticas.

Una cosa es posible que pueda hacer para mejorar el rendimiento podría ser poner un índice en la tabla temporal en el MID.

Revise su plan de ejecución para ver si ayuda (puede depender del número de filas de la tabla temporal).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top