Ano, můžete a můžete také přimět optimalizátor, aby to rozpoznal.
Paul White má tuhle malou maličkost :
WHERE NOT EXISTS (
SELECT d.[Data]
INTERSECT
SELECT i.[Data])
Toto funguje díky sémantice INTERSECT
které se zabývají nulami. To říká:„existují ne řádků v poddotazu tvořeném hodnotou B a hodnotou B", bude splněno pouze v případě, že se jedná o různé hodnoty nebo pokud jedna je nulová a druhá ne. Pokud jsou obě nulové, bude zde řádek s nulou.
Pokud zkontrolujete plán dotazů XML (nikoli grafický v SSMS), uvidíte, že se zkompiluje až do d.[Data] <> i.[Data]
, ale operátor, který používá, bude mít CompareOp="IS"
a ne EQ
.
Úplný plán naleznete zde .
Relevantní část plánu je:
<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>
Zjistil jsem, že optimalizátor funguje velmi dobře tímto způsobem, spíše než dělat EXISTS / EXCEPT
.
Vyzývám vás, abyste hlasovali pro Azure Feedback implementovat řádný operátora