Rozważ następujące zapytanie:
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);
Statystyka we / wy daje następujące wyniki:
Tabela „ParameterType”. Liczba skanów 0, logiczne odczyty 2, fizyczne odczyty 0, odczyt z wyprzedzeniem 0, lob logiczne odczyty 0, lob fizyczne odczyty 0, lob odczyty z wyprzedzeniem 0.
Tabela „Obszar”. Liczba skanów 0, logiczne odczyty 2, fizyczne odczyty 0, odczyt z wyprzedzeniem 0, lob logiczne odczyty 0, lob fizyczne odczyty 0, lob odczyty z wyprzedzeniem 0.
Tabela „Parametr”. Liczba skanów 1, logiczne odczyty 4, fizyczne odczyty 0, odczyt z wyprzedzeniem 0, lob logiczne odczyty 0, lob fizyczne odczyty 0, lob odczyty z wyprzedzeniem 0.
Tabela „Tabela robocza”. Liczba skanów 1, logiczne odczyty 0, fizyczne odczyty 0, odczyt z wyprzedzeniem 0, lob logiczne odczyty 0, lob fizyczne odczyty 0, lob odczyty z wyprzedzeniem 0.
Stół roboczy pojawia się w zakładce wiadomości, co sprawia, że myślę, że używa tempdb MERGE
.
W planie wykonania nie widzę niczego, co wskazywałoby na potrzebę użycia tempdb
Czy MERGE
zawsze używa tempdb?
Czy w BOL jest coś, co tłumaczy to zachowanie?
Czy użycie INSERT
i UPDATE
byłoby szybsze w tej sytuacji?
Lewo
Dobrze
Oto struktura tabeli
źródło
tempdb
. Wydaje się dziwne, że jest tam dla jednego rzędu. Myślę, że może tam być do ochrony Halloween.Odpowiedzi:
(Rozszerzając mój komentarz do pytania.)
Bez wyjątkowego ograniczenia kombinacji
AreaId
iParameterTypeId
podany kod jest łamany, ponieważ@UpdatedId = target.Id
zapisuje tylko jeden wierszId
.O ile nie powiesz tego, SQL Server nie może domyślnie znać możliwych stanów danych. Albo należy wymusić ograniczenie, albo jeśli wiele wierszy jest poprawnych , należy zmienić kod, aby użyć innego mechanizmu do wyprowadzania
Id
wartości.Ze względu na możliwość, że operator skanowania natrafi na wiele pasujących wierszy, zapytanie musi chętnie buforować wszystkie dopasowania dla ochrony Halloween. Jak wskazano w komentarzach, ograniczenie jest prawidłowe, więc dodanie go nie tylko zmieni plan ze skanowania na wyszukiwanie, ale także wyeliminuje potrzebę buforowania tabeli, ponieważ SQL Server będzie wiedział, że będzie albo 0, albo 1 wiersz zwrócony od operatora wyszukiwania.
źródło
Jeśli aktualizacja może zmienić pozycję wiersza w indeksie skanowanym przez aktualizację, SQL Server musi chronić przed problemem Halloween . W tym celu SQL Server zwykle wstawia chętny bufor tabeli do planu wykonania zaraz po skanowaniu indeksu. Ten operator tworzy kopię danych wierszy i używa do tego tempdb.
Aktualizacja części instrukcji MERGE musi być zgodna z tymi samymi zasadami, a także używa buforu tabeli w większości przypadków, w których wymagana jest ochrona Halloween.
Chociaż nie wiem, czy tak jest w twoim zapytaniu, ponieważ nie znam definicji definicji, najprawdopodobniej dzieje się tutaj.
źródło