Да, можете и можете да накарате оптимизатора също да го разпознае.
Пол Уайт има тази малка песен :
WHERE NOT EXISTS (
SELECT d.[Data]
INTERSECT
SELECT i.[Data])
Това работи поради семантиката на INTERSECT
които се занимават с нули. Това казва „има ли не редове в подзаявката, съставена от стойност B и стойност B", това ще бъде изпълнено само ако те са различни стойности или едната е нула, а другата не. Ако и двете са нула, ще има ред с нула.
Ако проверите плана на XML заявката (не графичния в SSMS), ще видите, че той се компилира до d.[Data] <> i.[Data]
, но операторът, който използва, ще има CompareOp="IS"
а не EQ
.
Вижте пълния план тук .
Съответната част от плана е:
<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>
Намирам, че оптимизаторът работи много добре по този начин, вместо да прави EXISTS / EXCEPT
.
Призовавам ви да гласувате за Azure Feedback за прилагане на правилен оператор