Dua kueri yang menyebabkan kebuntuan adalah SELECT
di bawah ini (process id="process3980de4558"
):
select @existing = team_it_cube_attr_05 from tbl_Ref_Attr_Prod_Team where prod_id = @rec_key
Dan UPDATE
kueri di bawah ini (process id="process386ed48188"
):
UPDATE D
SET D.team_rss_attr_01 = LEFT(S.mkt_prodchar_13,25)...
<resource-list>
bagian mencatat SELECT
kueri memiliki kunci (X) eksklusif pada halaman dan mencoba memperoleh kunci yang dibagikan maksud (IS) di halaman lain saat sedang membaca data. UPDATE
kueri sudah memiliki kunci IS dan mencoba untuk mendapatkan kunci X pada halaman untuk melakukan pembaruan.
Mengingat gabungan terhadap tabel ini:
...from tbl_Ref_Attr_Prod_Team where prod_id = @rec_key...
...INNER JOIN tbl_Ref_Attr_Prod_Team D ON D.prod_key=P.prod_key...
SELECT
kueri sudah memiliki kunci eksklusif. Ini mungkin berarti bahwa ini adalah bagian dari transaksi yang lebih besar yang telah melakukan UPDATE
dalam kueri sebelumnya. Kunci dari kueri sebelumnya akan dipertahankan untuk menjaga integritas data selama transaksi (bergantung pada tingkat isolasi transaksi
).
UPDATE
kueri perlu membaca tabel tbl_Ref_Attr_Prod_team
. Ini memperoleh kunci bersama maksud pada halaman dan baris saat membaca data. Saat UPDATE
kueri menemukan baris yang cocok, ia akan mencoba mengubah kunci IS menjadi kunci X. Kunci IS tidak kompatibel dengan kunci X. Karena SELECT
kueri sudah memiliki kunci IS pada satu atau beberapa halaman tersebut, kueri menemui jalan buntu satu sama lain.
Salah satu kemungkinan penyebabnya adalah hilangnya indeks pada tbl_Ref_Attr_Prod_team.prod_key
. Tanpa indeks pada kolom ini, UPDATE
kueri akan memindai semua baris dalam tabel tbl_Ref_Attr_Prod_team
.
Bahkan jika indeks ada di prod_key
, jika ada sejumlah kecil baris dalam tabel, SQL Server dapat memutuskan bahwa kinerja akan lebih baik jika kueri memindai seluruh tabel daripada mencari indeks. Merekam rencana kueri ketika kebuntuan terjadi akan memverifikasi teori ini.
Kami menemukan kebuntuan tabel kecil secara teratur saat membuat database baru. Awalnya, tabelnya kecil, dan pemindaian tabel menyebabkan segala macam kebuntuan. Kemudian, ketika tabel lebih besar, biaya pemindaian tabel yang dihitung melebihi biaya pencarian indeks, dan kebuntuan tidak lagi terjadi. Dalam lingkungan pengujian di mana jumlah baris selalu kecil, kami terpaksa menggunakan FORESEEK
dan WITH INDEX
petunjuk untuk memaksa pencarian indeks alih-alih pemindaian. Kami berharap dapat memaksakan rencana kueri melalui fitur penyimpanan kueri SQL Server 2016.