sql >> Base de Datos >  >> RDS >> Sqlserver

La consulta se ejecuta lentamente con la expresión de fecha, pero rápido con el literal de cadena

Esto podría funcionar mejor:

Where FK.DT = cast(getdate() + 1 - datepart(day, getdate()) as date)

A menos que esté ejecutando con el indicador de seguimiento 4199, hay un error que afecta las estimaciones de cardinalidad. Al momento de escribir

SELECT DATEADD(m, DATEDIFF(m, getdate(), 0), 0), 
       DATEADD(m, DATEDIFF(m, 0, getdate()), 0)

Devoluciones

+-------------------------+-------------------------+
| 1786-06-01 00:00:00.000 | 2013-08-01 00:00:00.000 |
+-------------------------+-------------------------+

El error es que el predicado en la pregunta usa la primera fecha en lugar de la segunda al derivar las estimaciones de cardinalidad. Así que para la siguiente configuración.

CREATE TABLE FK
(
ID INT IDENTITY PRIMARY KEY,
DT DATE,
Filler CHAR(1000) NULL,
UNIQUE (DT,ID)
)

INSERT INTO FK (DT)
SELECT TOP (1000000) DATEADD(m, DATEDIFF(m, getdate(), 0), 0)
FROM master..spt_values o1, master..spt_values o2
UNION ALL
SELECT               DATEADD(m, DATEDIFF(m, 0, getdate()), 0)

Consulta 1

SELECT COUNT(Filler)
FROM FK
WHERE FK.DT = CAST(DATEADD(m, DATEDIFF(m, 0, getdate()), 0) AS DATE)  

Estima que el número de filas coincidentes será de 100.000. Este es el número que coincide con la fecha '1786-06-01' .

Pero las dos consultas siguientes

SELECT COUNT(Filler)
FROM FK
WHERE FK.DT = CAST(GETDATE() + 1 - DATEPART(DAY, GETDATE()) AS DATE)

SELECT COUNT(Filler)
FROM FK
WHERE FK.DT = CAST(DATEADD(m, DATEDIFF(m, 0, getdate()), 0) AS DATE)  
OPTION (QUERYTRACEON 4199)

Regala este plan

Debido a las estimaciones de cardinalidad mucho más precisas, el plan ahora solo realiza una búsqueda de índice única en lugar de una exploración completa.