Ich habe den gefilterten Index unten erstellt. Wenn ich jedoch die 2 Abfragen weiter unten ausführe, wird dieser Index nur für eine Suche im ersten Beispiel verwendet, das END_DTTM in JOIN anstelle der where-Klausel enthält (das ist der einzige Unterschied in den Abfragen). . Kann jemand erklären, warum das passiert?
Indexerstellung
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)
Abfragen
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
Die beiden Abfragen sind unterschiedlich - in Bedeutung und Ergebnissen. Hier ist eine Umschreibung, daher ist es offensichtlicher, was die beiden Abfragen tun:
und 2 .:
Ich denke, es ist jetzt ziemlich offensichtlich, dass für den zweiten Teil der 2nq-Abfrage der gefilterte Index nicht verwendet werden kann.
Im Detail gibt es in Bezug auf diese Abfragen 4 Arten von
LIST_ID
Werten in der ersten Tabelle:(a) Werte mit übereinstimmenden Zeilen in der zweiten Tabelle, alle mit
END_DTTM IS NULL
.(b) Werte mit übereinstimmenden Zeilen in der zweiten Tabelle, sowohl mit
END_DTTM IS NULL
als auch mitEND_DTTM IS NOT NULL
.(c) Werte mit übereinstimmenden Zeilen in der zweiten Tabelle, alle mit
END_DTTM IS NOT NULL
.(d) Werte, die keine übereinstimmenden Zeilen in der zweiten Tabelle haben.
Jetzt gibt die erste Abfrage alle Werte vom Typ (a) und (b) möglicherweise mehrmals (so viele wie sie eine übereinstimmende Zeile in der zweiten Tabelle mit haben
END_DTTM IS NULL
) und alle Zeilen vom Typ (c) und (d) genau einmal zurück ( das ist der nicht übereinstimmende Teil des äußeren Joins).Die zweite Abfrage gibt alle Werte vom Typ (a) und (b) möglicherweise mehrmals (so viele wie sie eine übereinstimmende Zeile in der zweiten Tabelle mit haben
END_DTTM IS NULL
) und alle Zeilen vom Typ (d) genau einmal zurück.Es wird kein Wert vom Typ (c) zurückgegeben, da der Join übereinstimmende Zeilen in der zweiten Tabelle findet (diese jedoch haben
END_DTTM IS NOT NULL
) und diese durch die nachfolgendeWHERE
Klausel entfernt werden.quelle