Dlaczego aktualizacja dla tabeli z wyzwalaczem INSTEAD OF UPD wydaje się wstawiać indeks klastrowany, a także aktualizować indeks klastrowany?

10

Zacznę od bardzo prostego przykładu: dwie tabele, obie z tym samym schematem, zgrupowane w PK, ale jedna z nich ma INSTEAD OF UPDATEwyzwalacz:

CREATE TABLE Standard
(
    PK  UNIQUEIDENTIFIER PRIMARY KEY CLUSTERED,
    V   INT NOT NULL
)
GO

CREATE TABLE InsteadOf
(
    PK  UNIQUEIDENTIFIER PRIMARY KEY CLUSTERED,
    V   INT NOT NULL
)
GO

INSERT Standard (PK, V) VALUES ('1E58B555-B073-471E-B576-4B09C8E18976', 0)
INSERT InsteadOf (PK, V) VALUES ('1E58B555-B073-471E-B576-4B09C8E18976', 0)
GO

CREATE TRIGGER TR_InsteadOf_Update ON InsteadOf INSTEAD OF UPDATE
AS
BEGIN
    DECLARE @PK UNIQUEIDENTIFIER
    DECLARE @V INT
    DECLARE @cursor CURSOR
    SET @cursor = CURSOR FOR SELECT PK, V FROM Inserted
    OPEN @cursor

    FETCH NEXT FROM @cursor INTO @PK, @V
    WHILE @@FETCH_STATUS = 0
    BEGIN
        UPDATE InsteadOf SET
            V = @V
        WHERE PK = @PK

        FETCH NEXT FROM @cursor INTO @PK, @V
    END
    CLOSE @cursor
    DEALLOCATE @cursor

END
GO

Jeśli przeglądam plan zapytań o aktualizację w stosunku do standardowej tabeli, otrzymuję oczekiwaną aktualizację indeksu klastrowego:

UPDATE Standard SET
    V = 1
    WHERE PK = '1E58B555-B073-471E-B576-4B09C8E18976'

wprowadź opis zdjęcia tutaj

Jeśli jednak wykonam podobną aktualizację tabeli z wyzwalaczem, otrzymam coś, co wydaje się być wstawką indeksu klastrowego, a także aktualizację indeksu klastrowanego:

UPDATE InsteadOf SET
    V = 1
    WHERE PK = '1E58B555-B073-471E-B576-4B09C8E18976'

wprowadź opis zdjęcia tutaj

Dlaczego to? Widzę aktualizację indeksu klastrowego, której oczekiwałem później w tym planie zapytań (zapytanie nr 4), ale dlaczego otrzymuję tę dodatkową wstawkę w zapytaniu nr 1?

stusmith
źródło

Odpowiedzi:

10

An INSTEAD OFsklepy spustowe kopię wierszy, które zostaną dotknięte w ukrytej stołu roboczego *. To jest wstawka indeksu klastrowanego, którą widzisz. Treść wyzwalacza czyta z tej tabeli roboczej *, a wszelkie zmiany danych w wyzwalaczu używają „normalnego” operatora (w twoim przykładzie aktualizacja indeksów klastrowanych).


* Procesor zapytań wewnętrznie zmienia nazwę tabeli roboczej podczas tworzenia widocznej dla użytkownika formy planu wykonania. Pisząc do niego, jest on przemianowany na tabeli podstawowej cel, podczas czytania, jest przemianowany insertedlub deletedbardziej lub mniej jak ludzie oczekują na spuście.

Aby uzyskać więcej informacji, zobacz mój artykuł Interesujące rzeczy na temat INSTEAD OF wyzwalaczy .

Paul White 9
źródło