Tak, możesz i możesz sprawić, by optymalizator też to rozpoznał.
Paul White ma tę małą zabawkę :
WHERE NOT EXISTS (
SELECT d.[Data]
INTERSECT
SELECT i.[Data])
Działa to ze względu na semantykę INTERSECT
które zajmują się wartościami null. To, co mówi, to „czy nie? wierszy w podzapytaniu składającym się z wartości B i wartości B", zostanie to spełnione tylko wtedy, gdy są to różne wartości lub jedna ma wartość null, a druga nie. Jeśli obie są wartościami null, pojawi się wiersz z wartością null.
Jeśli sprawdzisz plan zapytań XML (nie graficzny w SSMS), zobaczysz, że kompiluje się aż do d.[Data] <> i.[Data]
, ale używany operator będzie miał CompareOp="IS"
a nie EQ
.
Zobacz pełny plan tutaj .
Odpowiednia część planu to:
<Predicate>
<ScalarOperator ScalarString="@t1.[i] as [t1].[i] = @t2.[i] as [t2].[i]">
<Compare CompareOp="IS">
<ScalarOperator>
<Identifier>
<ColumnReference Table="@t1" Alias="[t1]" Column="i" />
</Identifier>
</ScalarOperator>
<ScalarOperator>
<Identifier>
<ColumnReference Table="@t2" Alias="[t2]" Column="i" />
</Identifier>
</ScalarOperator>
</Compare>
</ScalarOperator>
</Predicate>
Uważam, że optymalizator działa bardzo dobrze w ten sposób, zamiast wykonywać EXISTS / EXCEPT
.
Zachęcam do głosowania na Opinia Azure zaimplementować odpowiedniego operatora