stored log last executed compilar sql tsql stored-procedures performance

log - La mejor forma de verificar la fecha actual en donde la cláusula de la consulta sql



sql server log stored procedure execution (7)

Estoy tratando de encontrar el modo más eficiente (mejor rendimiento) para verificar el campo de fecha para la fecha actual. Actualmente estamos usando:

SELECT COUNT(Job) AS Jobs FROM dbo.Job WHERE (Received BETWEEN DATEADD(d, DATEDIFF(d, 0, GETDATE()), 0) AND DATEADD(d, DATEDIFF(d, 0, GETDATE()), 1))


No estoy seguro de cómo estás definiendo "lo mejor", pero funcionará bien.

Sin embargo, si esta consulta es algo que ejecutará repetidamente, debería deshacerse de la función get_date () y simplemente ingresar un valor de fecha literal allí a través del lenguaje de programación en el que esté ejecutando esto. A pesar de que su salida cambia solo una vez cada 24 horas, get_date (), current_date (), etc. son funciones no deterministas , lo que significa que su RDMS probablemente invalidará la consulta como candidato para almacenarla en su caché de consultas si tiene una.


Que tal si

WHERE DATEDIFF(d, Received, GETDATE()) = 0


esa es la mejor manera de hacerlo. podría poner DATEADD (d, DATEDIFF (d, 0, GETDATE ()), 0) y DATEADD (d, DATEDIFF (d, 0, GETDATE ()), 1) en variables y usarlas en su lugar, pero no lo hago piensa que esto mejorará el rendimiento.


Si desea rendimiento, desea un golpe directo en el índice, sin CPU, etc. por fila; como tal, calcularía el rango primero , y luego usaría una consulta WHERE simple. No sé qué db estás usando, pero en SQL Server, lo siguiente funciona:

// ... where @When is the date-and-time we have (perhaps from GETDATE()) DECLARE @DayStart datetime, @DayEnd datetime SET @DayStart = CAST(FLOOR(CAST(@When as float)) as datetime) -- get day only SET @DayEnd = DATEADD(d, 1, @DayStart) SELECT COUNT(Job) AS Jobs FROM dbo.Job WHERE (Received >= @DayStart AND Received < @DayEnd)


WHERE DateDiff(d, Received, GETDATE()) = 0

Editar: Como se alinea en los comentarios a esta respuesta, esa no es una solución ideal. Verifique las otras respuestas en este hilo, también.


Normalmente usaría la solución sugerida por Tomalak , pero si realmente está desesperado por el rendimiento, la mejor opción podría ser agregar un campo indexado adicional ReceivedDataPartOnly, que almacenaría datos sin la parte de tiempo y luego usaría la consulta.

declare @today as datetime set @today = datediff(d, 0, getdate()) select count(job) as jobs from dbo.job where received_DatePartOnly = @today


Si solo desea buscar todos los registros donde se encuentra la fecha de recepción, y hay registros con futuras fechas de recepción, entonces lo que está haciendo es (muy ligeramente) incorrecto ... porque el operador Entre permite valores que son iguales hasta el límite final, por lo que podría obtener registros con Fecha de recepción = hasta la medianoche de mañana ...

Si no es necesario utilizar un índice en Recibido, todo lo que necesita hacer es verificar que la diferencia de fecha con la fecha y hora actual sea 0 ...

Where DateDiff(day, received, getdate()) = 0

Este predicado, por supuesto, no es SARGABLE, por lo que no puede usar un índice ... Si esto es un problema para esta consulta, entonces, suponiendo que no pueda tener fechas Recibidas en el futuro, usaría esto en su lugar ...

Where Received >= DateAdd(day, DateDiff(Day, 0, getDate()), 0)

Si las fechas Recibidas pueden estar en el futuro, entonces es probable que esté lo más cerca posible a la más eficiente ... (Excepto cambiar el Entre a a> = AND <)