Database transaksional digunakan untuk pemesanan barang ...
Vendor kami diminta untuk mengganti #temptable dengan @tablevariables (karena kunci kompilasi yang berat) tetapi sebaliknya mereka diganti dengan tabel aktual yang menambahkan SPID sebagai kolom untuk memastikan prosedur yang tersimpan hanya bekerja pada baris yang berlaku.
Apakah Anda melihat risiko dalam metode operasi ini? Sebelum semua transaksi diisolasi dalam transaksi mereka sendiri ... Saya khawatir kita mungkin akhirnya mengunci tabel ini banyak, tetapi pendapat mereka adalah bahwa SQL menggunakan penguncian tingkat-baris dan ini tidak akan membuat lebih banyak kunci.
SQL Server Versi: 2016 Enterprise - 13.0.5216.0
CREATE TABLE dbo.qryTransactions (
ID int IDENTITY (0,1) NOT NULL CONSTRAINT pk_qryTransactions PRIMARY KEY CLUSTERED,
spid int NOT NULL,
OrderID int,
ItemID int,
TimeTransactionStart datetime,
TimeTransactionEnd datetime,
...other fields
)
CREATE INDEX idx_qryTransactions_spidID ON qryTransactions (spid, ID) INCLUDE (ItemID, OrderID, TimeTransactionStart, TimeTransactionEnd)
Jawaban:
Sedikit lebih bertele-tele daripada yang dapat ditampung dalam blok komentar ... dan ingin menyoroti komentar OP yang dibuat dalam menanggapi jawaban Ray:
Berangkat sedikit menyinggung sebentar ... tentang apa yang akan terjadi dengan skenario ini adalah Sybase ASE ...
Kembali ke masalah OP (kompilasi kunci pada proc anak) ...
Adapun gagasan menggunakan tabel permanen tunggal dengan @@ SPID untuk membedakan baris antara sesi ... pernah ada, melihat bahwa ... yuck ; masalah berulang:
Saya ingin kembali dan (kembali) menyelidiki masalah root (kunci kompilasi pada proc anak) dan melihat apakah ada cara untuk mengurangi (menghilangkan?) Kata kunci kompilasi. [Sayangnya pengetahuan SQL Server saya tentang masalah ini adalah ... NULL ... jadi akan tertarik pada masukan dari beberapa ahli kompiler SQL Server.]
sumber
Sepertinya saya menggunakan
@@SPID
yang meminta masalah.ID sesi sering digunakan kembali; segera setelah koneksi pengguna keluar, ID sesi itu tersedia untuk digunakan lagi, dan kemungkinan akan digunakan oleh sesi berikutnya yang mencoba untuk terhubung.
Untuk membuatnya berfungsi setidaknya semi-andal, Anda memerlukan pemicu masuk yang membersihkan baris sebelumnya dari tabel dengan yang sama
@@SPID
. Jika Anda melakukannya, Anda cenderung melihat banyak penguncian di atas meja menggunakan@@SPID
kolom.SQL Server memang menggunakan penguncian baris, tetapi juga menggunakan penguncian halaman, dan penguncian tabel. Tentu saja, Anda mungkin dapat mengurangi itu melalui pengindeksan yang baik, tetapi ini masih terlihat seperti anti-pola bagi saya.
Jika prosedur tersimpan adalah satu - satunya metode yang digunakan untuk mengakses tabel yang terpengaruh, Anda dapat menyelidiki dengan menggunakan kunci aplikasi, melalui
sp_getapplock
untuk pada dasarnya membuat serial akses ke bagian yang relevan. Documents untuk sp_getapplock ada di sini . Erik Darling memiliki pos yang menarik tentang hal itu di sini .sumber
Ya, saya melihat risiko. Adalah naif untuk mengandalkan SQL menggunakan Penguncian Baris. Misalnya, saya cukup yakin memasukkan dan menghapus akan menggunakan kunci halaman setidaknya. SQL Engine memilih jenis kunci berdasarkan beberapa faktor dan tidak satu pun dari faktor tersebut termasuk "pendapat mereka". Solusi selimut seperti mengubah variabel tabel temp ke tabel umumnya juga merupakan ide yang buruk. Variabel tabel sangat berguna dalam beberapa situasi tetapi mereka memang memiliki keterbatasan dan masalah kinerja. Saya lebih suka tabel temp di sebagian besar keadaan. Terutama ketika meja akan menampung lebih dari beberapa lusin baris. Saya akan meminta vendor untuk menjelaskan mengapa sistem mengalami "kunci kompilasi berat" dan bagaimana itu menurunkan kinerja. Ingat, kapan pun Anda melihatnya, Anda akan menemukan "kunci berat". Itu tidak berarti bahwa kunci adalah masalah. Maks ' Komentar tentang @@ SPID juga penting. Selain itu, model transaksi dan pemrosesan kesalahan bisa menjadi masalah besar. Jika sistem Anda mengalami kebuntuan atau menginput masalah kualitas data maka pemrosesan kesalahan standar dapat mengakibatkan sesi dihentikan tanpa tabel qryTransactions sedang diatur ulang dengan benar. IMO pendekatan solusi yang salah dengan masalah aslinya.
sumber