Verwendet MERGE Tempdb?


12

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 MERGEimmer tempdb verwenden?

Gibt es irgendetwas in BOL, das dieses Verhalten erklärt?

Wäre die Verwendung von INSERT& UPDATEin dieser Situation schneller?

Links

Bildbeschreibung hier eingeben

Richtig

Bildbeschreibung hier eingeben

Hier ist die Tabellenstruktur

Bildbeschreibung hier eingeben


Die Spule im Plan ist ein Arbeitstisch tempdb. Scheint seltsam, dass es für eine einzelne Zeile da ist. Ich vermute, es könnte zum Halloween-Schutz da sein.
Martin Smith

Ich sehe es jetzt. Speichert die Daten aus der Eingabe in einer temporären Tabelle, um das Zurückspulen zu optimieren.
Craig Efrein

Antworten:


8

(Mein Kommentar zur Frage wird erweitert.)

Ohne eine eindeutige Einschränkung für die Kombination von AreaIdund ParameterTypeIdist der angegebene Code fehlerhaft, da @UpdatedId = target.Idimmer nur eine einzelne Zeile aufgezeichnet wird Id.

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


6

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.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.