Mengapa pemutakhiran terhadap tabel dengan BUKAN memicu pembaruan tampaknya melakukan memasukkan indeks berkerumun, serta pembaruan indeks berkerumun?

10

Saya akan mulai dengan contoh yang sangat sederhana: dua tabel, keduanya dengan skema yang sama, berkerumun di PK, tetapi salah satunya memiliki INSTEAD OF UPDATEpemicu:

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

Jika saya melihat rencana permintaan untuk pembaruan terhadap tabel standar, saya mendapatkan pembaruan indeks yang diharapkan:

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

masukkan deskripsi gambar di sini

Namun jika saya melakukan pembaruan yang serupa terhadap tabel dengan pemicu, saya mendapatkan apa yang tampaknya menjadi sisipan indeks berkerumun, serta pembaruan indeks berkerumun:

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

masukkan deskripsi gambar di sini

Kenapa ini? Saya bisa melihat pembaruan indeks berkerumun yang saya harapkan nanti dalam rencana kueri ini (kueri # 4), tetapi mengapa saya mendapatkan tambahan ini di kueri # 1?

tukang kayu
sumber

Jawaban:

10

Sebuah INSTEAD OFtoko pemicu salinan baris yang akan terpengaruh dalam tersembunyi meja kerja *. Ini adalah Indeks Masukkan Clustered yang Anda lihat. Badan pemicu membaca dari tabel kerja ini * dan setiap perubahan data dalam pemicu menggunakan operator 'normal' (Pembaruan Indeks Berkelompok dalam contoh Anda).


* Prosesor permintaan secara internal mengubah nama tabel kerja ketika membangun bentuk rencana eksekusi yang terlihat oleh pengguna. Saat menulis untuk itu, itu diganti namanya ke tabel basis target, saat membaca, itu diganti namanya menjadi insertedatau deletedlebih atau kurang seperti yang orang harapkan untuk melihat di pemicu.

Untuk detail lebih lanjut, lihat artikel saya Hal menarik tentang BUKAN pemicu .

Paul White 9
sumber