Чому, як видається, ОНОВЛЕННЯ проти таблиці з тригером INSTEAD OF UPDATE робить кластеризовану вкладку індексу, а також оновлення кластерного індексу?


10

Почну з дуже простого прикладу: дві таблиці, обидві з однаковою схемою, згруповані в ПК, але одна з яких має INSTEAD OF UPDATEтригер:

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

Якщо я переглядаю план запитів на оновлення до стандартної таблиці, я отримую очікуване оновлення індексу кластера:

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

введіть тут опис зображення

Однак якщо я виконую аналогічне оновлення таблиці проти тригера, я отримую кластерну вкладку індексу, а також кластерне оновлення індексу:

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

введіть тут опис зображення

Чому це? Я бачу кластерне оновлення індексу, яке я очікував пізніше в цьому плані запитів (запит №4), але чому я отримую цю додаткову вставку за запитом №1?

Відповіді:


10

An INSTEAD OFтригер зберігає копію рядка , які будуть порушені в прихованій роботі таблиця *. Це вставка кластерного індексу, яку ви бачите. Тіло тригера зчитує з цієї робочої таблиці *, а будь-які зміни даних в тригері використовують оператор «нормальний» (Clustered Index Update у вашому прикладі).


* Процесор запиту внутрішньо перейменовує робочу таблицю під час побудови видимої для користувача форми плану виконання. При записи на нього, він буде перейменований в цільової базової таблиці, при читанні, він перейменовується insertedабо deletedбільш-менш , як люди чекали б бачити в якості тригера.

Детальніше дивіться мою статтю Цікаві речі про ВСТАНОВИТИ тригери .

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.