Betrachten Sie die folgende Abfrage:
MERGE [Parameter] with (rowlock) AS target
USING (SELECT @AreaId, @ParameterTypeId, @Value)
AS source (AreaId, ParameterTypeId, Value)
ON (target.AreaId = source.AreaId AND
target.ParameterTypeId = source.ParameterTypeId)
WHEN MATCHED THEN
UPDATE SET target.Value = source.Value, @UpdatedId = target.Id
WHEN NOT MATCHED THEN
INSERT ([AreaId], [ParameterTypeId], [Value])
VALUES (source.AreaId, source.ParameterTypeId, source.Value);
Statistik-E / A liefert die folgende Ausgabe:
Tabelle 'ParameterType'. Scananzahl 0, logische Lesevorgänge 2, physische Lesevorgänge 0, Vorauslesevorgänge 0, logische Lobs-Lesevorgänge 0, physikalische Lobs-Lesevorgänge 0, Lobs-Vorauslesevorgänge 0.
Tabelle 'Bereich'. Scananzahl 0, logische Lesevorgänge 2, physische Lesevorgänge 0, Vorauslesevorgänge 0, logische Lobs-Lesevorgänge 0, physikalische Lobs-Lesevorgänge 0, Lobs-Vorauslesevorgänge 0.
Tabelle 'Parameter'. Scananzahl 1, logische Lesevorgänge 4, physische Lesevorgänge 0,
Vorlesevorgänge 0, logische Vorlesevorgänge 0, physische Vorlesevorgänge 0 , Vorlesevorgänge 0. Tabelle 'Arbeitstabelle'. Scanzählung 1, logische Lesevorgänge 0, physische Lesevorgänge 0, Vorlesevorgänge 0, logische Vorlesevorgänge 0, physische Vorlesevorgänge 0, Vorlesevorgänge 0.
Auf der Registerkarte mit den Nachrichten wird eine Arbeitstabelle angezeigt, die mich glauben lässt, dass Tempdb von verwendet wird MERGE
.
Ich sehe im Ausführungsplan nichts, was auf die Notwendigkeit von tempdb hindeutet
Hat MERGE
immer tempdb verwenden?
Gibt es irgendetwas in BOL, das dieses Verhalten erklärt?
Wäre die Verwendung von INSERT
& UPDATE
in dieser Situation schneller?
Links
Richtig
Hier ist die Tabellenstruktur
quelle
tempdb
. Scheint seltsam, dass es für eine einzelne Zeile da ist. Ich vermute, es könnte zum Halloween-Schutz da sein.Antworten:
(Mein Kommentar zur Frage wird erweitert.)
Ohne eine eindeutige Einschränkung für die Kombination von
AreaId
undParameterTypeId
ist der angegebene Code fehlerhaft, da@UpdatedId = target.Id
immer nur eine einzelne Zeile aufgezeichnet wirdId
.Wenn Sie dies nicht angeben, kann SQL Server die möglichen Zustände der Daten nicht implizit kennen. Entweder sollte die Einschränkung erzwungen werden, oder wenn mehrere Zeilen gültig sind , muss der Code geändert werden, um einen anderen Mechanismus für die Ausgabe der
Id
Werte zu verwenden.Aufgrund der Möglichkeit, dass der Scan-Operator auf mehrere übereinstimmende Zeilen stößt, muss die Abfrage alle Übereinstimmungen für den Halloween-Schutz spoolen. Wie in den Kommentaren angegeben, die Einschränkung ist gültig, es so Zugabe wird nicht nur den Plan von einem Scan ändern , um eine Suche, sondern auch die Notwendigkeit , dass die Tabelle Spule beseitigen, wie SQL Server wird wissen , dass es entweder 0 sein wird oder 1 Zeilen vom Suchoperator zurückgegeben.
quelle
Wenn das Update die Position der Zeile im vom Update durchsuchten Index ändern kann, muss SQL Server vor dem Halloween-Problem schützen . Dafür fügt SQL Server in der Regel unmittelbar nach dem Index-Scan einen eifrigen Tabellenspool in den Ausführungsplan ein. Dieser Operator erstellt im Grunde genommen eine Kopie der fraglichen Zeilen und verwendet dafür tempdb.
Der Update-Teil der MERGE-Anweisung muss den gleichen Regeln folgen und verwendet in den meisten Fällen, in denen Halloween-Schutz erforderlich ist, auch eine Tabellenspule.
Ich kann zwar nicht sagen, ob dies bei Ihrer Abfrage der Fall ist, da ich die Indexdefinition (en) nicht kenne, aber dies ist höchstwahrscheinlich das, was hier passiert.
quelle