2016-03-24 10 views
0

Ich möchte sehen, ob es möglich ist, die folgende Abfrage zu verbessern, die eine WHERE NOT EXISTS verwendet?Wie zu verbessern WHERE NOT EXISTS von einer INSERT-Anweisung

Ich möchte Datensätze aus einer anderen Tabelle zu einem neuen in Chargen von 500 hinzufügen, wo der Schlüssel in einer temporären Tabelle ist, es funktioniert, aber möchte seine Leistung verbessern, wenn möglich.

WHILE 1 = 1 

BEGIN 

INSERT INTO newTable WITH (TABLOCK) 
     SELECT TOP(500) * 
     FROM srcTable src 
     WHERE NOT EXISTS (SELECT 1 FROM newTable WHERE pKey = src.pKey 
          AND src.pKey IN (SELECT pKey FROM #TempTable)) 

IF @@ROWCOUNT < 500 BREAK 
END 

Vielen Dank!

+2

ich durch eine Erhöhung der Losgröße beginnen würde. 500 Reihen sind furchtbar klein. Ich würde denken, 10k wäre um den Wendepunkt, um schnelle, aber nicht zu viele Iterationen abzuschließen. –

+0

Wie viele Zeilen haben Sie in #TempTable? – FLICKER

+0

#TempTable hat 7072 Datensätze – Billy

Antwort

0

Es scheint seltsam, beide Bedingungen in die not exists zu setzen. Also ich denke:

INSERT INTO newTable WITH (TABLOCK) 
    SELECT TOP(500) * 
    FROM srcTable src 
    WHERE NOT EXISTS (SELECT 1 FROM newTable nt WHERE nt.pKey = src.pKey) AND 
      NOT EXISTS (SELECT 1 FROM #TempTable tt WHERE src.pKey = t.pkey); 

Dann wird für diese Abfrage würde ich Indizes auf newTable(pkey) und #TempTable(pkey) wollen.

Hinweis: Ich denke, ich habe diese Logik richtig. Ein wenig verwirrend ist es, einen IN in eine nicht verwandte Tabelle in einem korrelierten NOT EXISTS zu bringen.

EDIT:

Hmmm. . . Wenn ich die Logik falsch verstanden, dann wollen Sie nur EXISTS auf der zweiten Bedingung:

INSERT INTO newTable WITH (TABLOCK) 
    SELECT TOP(500) * 
    FROM srcTable src 
    WHERE NOT EXISTS (SELECT 1 FROM newTable nt WHERE nt.pKey = src.pKey) AND 
      EXISTS (SELECT 1 FROM #TempTable tt WHERE src.pKey = t.pkey); 
+0

Würde es irgendwelche Bedingungen geben, bei denen es effizienter wäre, einen 'inneren Join' zwischen srcTable und #TempTable zu machen, im Gegensatz zum 'not exist'-Formular? –

+0

@PhilipKelley. . . Ich kann mir keinen Weg vorstellen, "nicht vorhanden" durch einen "inneren Join" zu ersetzen. Sie können es durch "linker äußerer Anschluss" ersetzen, und ich schätze, die Leistung wäre vergleichbar. Zumindest wäre jede Version ('left join' und' not exist'/'not in') besser als die aktuelle Abfrage, da die erste besser optimiert würde. –

+0

Wie ich es lese, OP möchte Daten von newTable nur kopieren, wo ID in #temp Tabelle vorhanden ist, und nur wenn es noch nicht kopiert wurde. Fügen Sie also newTable auf #temp hinzu (erhalten Sie nur legitime Ziele), und kopieren Sie dann nur, wenn nicht bereits kopiert (wie mit "nicht vorhanden" markiert). –

Verwandte Themen