Eu criei o índice filtrado abaixo, no entanto, quando executo as 2 consultas mais abaixo, esse índice só é usado para uma pesquisa no primeiro exemplo que possui o END_DTTM na JOIN e não na cláusula where (essa é a única diferença nas consultas) . Alguém pode explicar por que isso acontece?
Criação 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
As duas consultas são diferentes - em significado e resultados. Aqui está uma reescrita, por isso é mais óbvio o que as duas consultas estão fazendo:
e 2º:
Eu acho que agora é bastante óbvio que, para a segunda parte da consulta 2nq, o índice filtrado não pode ser usado.
Em detalhes, em relação a essas consultas, existem 4 tipos de
LIST_ID
valores na primeira tabela:(a) valores que possuem linhas correspondentes na segunda tabela, todos com
END_DTTM IS NULL
.(b) valores que possuem linhas correspondentes na segunda tabela, com
END_DTTM IS NULL
e comEND_DTTM IS NOT NULL
.(c) valores que possuem linhas correspondentes na segunda tabela, todos com
END_DTTM IS NOT NULL
.(d) valores que não possuem linhas correspondentes na segunda tabela.
Agora, a primeira consulta retornará todos os valores do tipo (a) e (b) possivelmente várias vezes (quantas tiverem uma linha correspondente na segunda tabela com
END_DTTM IS NULL
) e todas as linhas do tipo (c) e (d) exatamente uma vez ( essa é a parte não correspondente da junção externa).A 2ª consulta retornará todos os valores do tipo (a) e (b) possivelmente várias vezes (quantas tiverem uma linha correspondente na segunda tabela com
END_DTTM IS NULL
) e todas as linhas do tipo (d) exatamente uma vez.Ele não retornará nenhum valor do tipo (c) porque a junção encontrará linhas correspondentes na segunda tabela (mas elas terão
END_DTTM IS NOT NULL
) e serão removidas pelaWHERE
cláusula subsequente .fonte