Creé el índice filtrado a continuación, sin embargo, cuando ejecuto las 2 consultas más abajo, este índice solo se usa para una búsqueda en el primer ejemplo que tiene END_DTTM en JOIN en lugar de la cláusula where (esa es la única diferencia en las consultas) . ¿Alguien puede explicar por qué sucede esto?
Creación de índice
CREATE NONCLUSTERED INDEX [ix_PATIENT_LIST_BESPOKE_LIST_ID_includes] ON [dbo].[PATIENT_LIST_BESPOKE]
(
[LIST_ID] ASC,
[END_DTTM] ASC
)
WHERE ([END_DTTM] IS NULL)
Consultas
DECLARE @LIST_ID INT = 3655
--This one seeks on the index
SELECT
PATIENT_LISTS.LIST_ID
FROM
DBO.PATIENT_LISTS
LEFT JOIN DBO.PATIENT_LIST_BESPOKE ON PATIENT_LISTS.LIST_ID = PATIENT_LIST_BESPOKE.LIST_ID
AND PATIENT_LIST_BESPOKE.END_DTTM IS NULL
WHERE
PATIENT_LISTS.LIST_ID = @LIST_ID
--This one scans on the index
SELECT
PATIENT_LISTS.LIST_ID
FROM
DBO.PATIENT_LISTS
LEFT JOIN DBO.PATIENT_LIST_BESPOKE ON PATIENT_LISTS.LIST_ID = PATIENT_LIST_BESPOKE.LIST_ID
WHERE
PATIENT_LISTS.LIST_ID = @LIST_ID AND
PATIENT_LIST_BESPOKE.END_DTTM IS NULL
Las dos consultas son diferentes: en significado y resultados. Aquí hay una reescritura, por lo que es más obvio lo que están haciendo las dos consultas:
y 2do:
Creo que ahora es bastante obvio que para la segunda parte de la consulta 2nq, el índice filtrado no se puede usar.
En detalle, con respecto a estas consultas, hay 4 tipos de
LIST_ID
valores en la primera tabla:(a) valores que tienen filas coincidentes en la segunda tabla, todos con
END_DTTM IS NULL
.(b) valores que tienen filas coincidentes en la segunda tabla, tanto con
END_DTTM IS NULL
como conEND_DTTM IS NOT NULL
.(c) valores que tienen filas coincidentes en la segunda tabla, todos con
END_DTTM IS NOT NULL
.(d) valores que no tienen filas coincidentes en la segunda tabla.
Ahora, la primera consulta devolverá todos los valores de tipo (a) y (b) posiblemente muchas veces (tantas como tengan una fila coincidente en la segunda tabla con
END_DTTM IS NULL
) y todas las filas de tipo (c) y (d) exactamente una vez ( esa es la parte no coincidente de la unión externa).La segunda consulta devolverá todos los valores de tipo (a) y (b) posiblemente muchas veces (tantas como tengan una fila coincidente en la segunda tabla
END_DTTM IS NULL
) y todas las filas de tipo (d) exactamente una vez.Será no devolver ningún valor del tipo (c) debido a la unión encontrarán filas coincidentes en la segunda tabla (pero éstos tendrán
END_DTTM IS NOT NULL
) y que será eliminado por el posteriorWHERE
cláusula.fuente