Apakah MERGE menggunakan tempdb?

12

Pertimbangkan pertanyaan berikut:

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 I / O memberikan output berikut:

Tabel 'ParameterType'. Pindai hitungan 0, bacaan logis 2, bacaan fisik 0, bacaan baca-depan 0, bacaan logis lob 0, bacaan fisik lob 0, bacaan baca lob depan 0.
Tabel 'Area'. Pindai menghitung 0, bacaan logis 2, bacaan fisik 0, bacaan baca-depan 0, bacaan logis lob 0, bacaan fisik lob 0, bacaan lob baca-depan 0.
Tabel 'Parameter'. Pindai hitungan 1, bacaan logis 4, bacaan fisik 0, bacaan baca-depan 0, bacaan logis lob 0, bacaan fisik lob 0, baca bacaan lob depan 0.
Tabel 'Meja Kerja'. Pindai hitungan 1, bacaan logis 0, bacaan fisik 0, bacaan baca-depan 0, bacaan logis lob 0, bacaan fisik lob 0, bacaan lob baca-depan 0.

Meja kerja muncul di tab pesan yang membuat saya berpikir bahwa tempdb sedang digunakan oleh MERGE.

Saya tidak melihat apa pun dalam rencana Eksekusi yang akan menunjukkan perlunya tempdb

Apakah MERGEselalu menggunakan tempdb?

Apakah ada sesuatu di BOL yang menjelaskan perilaku ini?

Apakah menggunakan INSERT& UPDATElebih cepat dalam situasi ini?

Kiri

masukkan deskripsi gambar di sini

Baik

masukkan deskripsi gambar di sini

Berikut adalah struktur tabelnya

masukkan deskripsi gambar di sini

Craig Efrein
sumber
Gulungan dalam rencana adalah meja kerja di tempdb. Tampaknya aneh bahwa itu ada untuk satu baris sekalipun. Saya kira itu mungkin ada untuk perlindungan Halloween.
Martin Smith
Saya melihatnya sekarang. Menyimpan data dari input ke tabel sementara untuk mengoptimalkan rewinds.
Craig Efrein

Jawaban:

8

(Memperluas komentar saya pada pertanyaan.)

Tanpa kendala unik pada kombinasi AreaIddan ParameterTypeId, kode yang diberikan rusak karena @UpdatedId = target.Idhanya akan pernah merekam satu baris Id.

Kecuali Anda mengatakannya demikian, SQL Server tidak dapat secara implisit mengetahui keadaan data yang mungkin. Entah kendala harus ditegakkan, atau jika beberapa baris valid , kode perlu diubah untuk menggunakan mekanisme yang berbeda untuk menampilkan Idnilai - nilai.

Karena kemungkinan bahwa operator pemindaian akan menemukan beberapa baris yang cocok, kueri harus bersemangat semua kecocokan untuk perlindungan Halloween. Seperti yang ditunjukkan di komentar, kendala adalah valid, sehingga menambahkan tidak hanya akan mengubah rencana dari pindaian ke mencari, tetapi juga menghilangkan kebutuhan untuk spool meja, SQL Server akan tahu ada akan menjadi 0 atau 1 baris dikembalikan dari operator pencarian.

Jon Seigel
sumber
6

Jika pembaruan dapat mengubah posisi baris dalam indeks yang dipindai oleh pembaruan, SQL Server perlu melindungi dari Masalah Halloween . Untuk itu SQL Server biasanya memasukkan spool tabel bersemangat ke dalam rencana eksekusi tepat setelah pemindaian indeks. Operator itu pada dasarnya membuat salinan baris yang dipermasalahkan dan menggunakan tempdb untuk itu.

Bagian pembaruan dari pernyataan MERGE harus mengikuti aturan yang sama dan juga menggunakan spool tabel dalam banyak kasus di mana perlindungan Halloween diperlukan.

Meskipun saya tidak tahu apakah ini yang terjadi dalam permintaan Anda, karena saya tidak tahu definisi indeks, ini kemungkinan besar adalah apa yang terjadi di sini.

Sebastian Meine
sumber