Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Gibt es eine Möglichkeit, einen NULL-Vergleich von 2 Werten zu vereinfachen?

Ja, das können Sie, und Sie können das Optimierungsprogramm auch dazu bringen, es zu erkennen.

Paul White hat dieses kleine Liedchen :

WHERE NOT EXISTS (
    SELECT d.[Data]
    INTERSECT
    SELECT i.[Data])

Dies funktioniert aufgrund der Semantik von INTERSECT die mit Nullen umgehen. Was hier steht, ist:„Gibt es keine Zeilen in der Unterabfrage, die aus Wert B und Wert B bestehen", wird dies nur erfüllt, wenn es sich um unterschiedliche Werte handelt oder einer Null ist und der andere nicht. Wenn beide Nullen sind, gibt es eine Zeile mit einer Null.

Wenn Sie den XML-Abfrageplan (nicht den grafischen in SSMS) überprüfen, werden Sie feststellen, dass er bis hinunter zu d.[Data] <> i.[Data] kompiliert wird , aber der verwendete Operator wird CompareOp="IS" haben und nicht EQ .

Den vollständigen Plan finden Sie hier .

Der relevante Teil des Plans ist:

                <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>

Ich finde, dass der Optimierer auf diese Weise sehr gut funktioniert, anstatt EXISTS / EXCEPT zu machen .

Ich fordere Sie auf, für den Azure-Feedback um einen geeigneten Operator zu implementieren