Я создал отфильтрованный индекс ниже, однако, когда я запускаю 2 запроса дальше вниз, этот индекс используется только для поиска в первом примере, который имеет END_DTTM в JOIN, а не в предложении where (это единственная разница в запросах) , Кто-нибудь может объяснить, почему это происходит?
Создание индекса
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)
Запросы
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
Два запроса различны - по смыслу и результатам. Вот переписывание, поэтому более очевидно, что делают два запроса:
и 2-й:
Я думаю, что теперь совершенно очевидно, что для второй части запроса 2nq отфильтрованный индекс не может быть использован.
Подробно, относительно этих запросов,
LIST_ID
в первой таблице есть 4 типа значений:(a) значения, которые имеют совпадающие строки во второй таблице, все с
END_DTTM IS NULL
.(б) значения, которые имеют совпадающие строки во второй таблице, как с, так
END_DTTM IS NULL
и сEND_DTTM IS NOT NULL
.(c) значения, которые имеют совпадающие строки во второй таблице, все с
END_DTTM IS NOT NULL
.(d) значения, которые не имеют совпадающих строк во второй таблице.
Теперь 1-й запрос вернет все значения типа (a) и (b), возможно, много раз (столько, сколько у них совпадающей строки во второй таблице с
END_DTTM IS NULL
), и все строки типа (c) и (d) ровно один раз ( это несоответствующая часть внешнего соединения).Второй запрос вернет все значения типа (a) и (b), возможно, много раз (столько, сколько у них совпадающей строки во второй таблице с
END_DTTM IS NULL
) и все строки типа (d) ровно один раз.Он не будет возвращать никакого значения типа (c), потому что соединение найдет совпадающие строки во второй таблице (но они будут иметь
END_DTTM IS NOT NULL
), и они будут удалены последующимWHERE
предложением.источник