2016-07-26 6 views
3

Verwenden von SQL Server 2014:TSQL-Operatoren IN und INNER JOIN

Gibt es Leistungsunterschiede zwischen den folgenden Anweisungen?

DELETE FROM MyTable where PKID IN (SELECT PKID FROM @TmpTableVar) 

UND

DELETE FROM MyTable INNER JOIN @TmpTableVar t ON MyTable.PKID = t.PKID 
+5

Werfen Sie einen Blick auf die Ausführungspläne für jeden. In diesem Fall werden sie wahrscheinlich identisch sein. –

+0

Die Ausführungspläne basieren auf aktuellen Statistiken. Sie könnten heute identisch sein, ändern sich aber später. Deshalb suche ich nach breiteren Regeln. –

+0

Ich habe einige Tests gemacht, beide sind fast in allen Fällen ähnlich http://stackoverflow.com/questions/38444729/most-efficient-way-to-select-rows-where-the-id-exists-in-a-second -table/38445287 # 38445287 – TheGameiswar

Antwort

5

In Ihrem gegebenen Beispiel die Ausführungspläne werden die gleichen (höchstwahrscheinlich) sein.

Aber die gleichen Ausführungspläne zu haben bedeutet nicht, dass sie die besten Ausführungspläne sind, die Sie für diese Aussage haben können.

Das Problem, das ich in beiden Ihren Abfragen sehe, ist die Verwendung der Table Variable.

SQL Server geht immer davon aus, dass nur eine Zeile in der Tabellenvariablen vorhanden ist. Nur in SQL Server 2014 und höheren Versionen wurde diese Annahme in 100 Zeilen geändert.

Egal wie viele Zeilen Sie haben, die Tabellenvariable SQL Server wird immer davon ausgehen, dass Sie eine Zeile in der @TmpTableVar haben.

Sie können Ihren Code geringfügig ändern, um SQL Server eine bessere Vorstellung davon zu geben, wie viele Zeilen in dieser Tabelle enthalten sein werden, indem Sie ihn durch Temporary table ersetzen, und da es sich um eine PK_ID Spalte handelt, können Sie auch einen Index erstellen auf dieser Tabelle, um dem SQL-Server die bestmögliche Chance zu geben, den bestmöglichen Ausführungsplan für diese Abfrage zu erstellen.

SELECT PKID INTO #Temp 
FROM @TmpTableVar 

-- Create some index on the temp table here ..... 

DELETE FROM MyTable 
WHERE EXISTS (SELECT 1 
       FROM #Temp t 
       WHERE MyTable.PKID = t.PKID) 

Hinweis

In Operator wird gut funktionieren, da es sich um eine Primärschlüsselspalte in der Tabelle variabel ist. Wenn Sie jedoch jemals den Operator IN für eine Spalte mit NULL-Wert verwenden, werden Sie die Ergebnisse möglicherweise überraschen. Der Operator IN wird in Birnbaumform angezeigt, sobald in der Spalte, die er überprüft, NULL-Werte gefunden werden.

Ich persönlich bevorzuge Exists-Operator für solche Abfragen, aber innere Joins sollten auch gut funktionieren, aber vermeiden Sie IN-Operatoren, wenn Sie können.

+0

Vielen Dank für Ihre Hilfe. Betrifft die Anzahl der Zeilen, die sich um @tableVariables beziehen, auch den inneren Join-Ansatz? Ich denke darüber nachzudenken, den inneren Beitritt als sichereren Ansatz zu betrachten. –

+0

Kein Problem, und ja, es kann dazu führen, dass SQL Server einen weniger effizienten Ausführungsplan erstellt, weil SQL Server davon ausgeht, dass nur eine Zeile in der Tabelle vorhanden ist. Ein Join in der Primärschlüsselspalte sollte nur eine Zeile zurückbringen. Dies könnte jedoch nicht der Fall sein. Vermeiden Sie daher die Verwendung von Tabellenvariablen in solchen Szenarien. –