Pengaruh petunjuk NOLOCK dalam pernyataan SELECT

199

Saya kira pertanyaan sebenarnya adalah:

Jika saya tidak peduli dengan pembacaan yang kotor, akan menambahkan petunjuk with (NOLOCK) ke pernyataan SELECT mempengaruhi kinerja:

  1. pernyataan SELECT saat ini
  2. transaksi lainnya terhadap tabel yang diberikan

Contoh:

Select * 
from aTable with (NOLOCK)
Bob Probst
sumber
3
Ini SO dan DBA jawaban yang sedikit lebih jelas seperti apa yang sebenarnya terjadi.
Ditebangi

Jawaban:

289

1) Ya , pilih dengan NOLOCKakan menyelesaikan lebih cepat dari pilih normal.

2) Ya , pilih dengan NOLOCKakan memungkinkan kueri lain terhadap tabel yang dilakukan untuk menyelesaikan lebih cepat dari pilih normal.

Mengapa ini terjadi?

NOLOCKbiasanya (tergantung pada mesin DB Anda) berarti memberi saya data Anda, dan saya tidak peduli keadaan apa itu, dan jangan repot-repot menahannya saat Anda membaca dari itu. Semuanya sekaligus lebih cepat, kurang intensif sumber daya, dan sangat sangat berbahaya.

Anda harus diperingatkan untuk tidak pernah melakukan pembaruan dari atau melakukan sistem apa pun kritis, atau di mana kebenaran mutlak diperlukan menggunakan data yang berasal dari NOLOCKmembaca. Sangat mungkin bahwa data ini berisi baris yang telah dihapus selama menjalankan kueri atau yang telah dihapus di sesi lain yang belum selesai. Ada kemungkinan bahwa data ini termasuk baris yang sebagian telah diperbarui. Ada kemungkinan bahwa data ini berisi catatan yang melanggar batasan kunci asing. Ada kemungkinan bahwa data ini mengecualikan baris yang telah ditambahkan ke tabel tetapi belum dilakukan.

Anda benar-benar tidak memiliki cara untuk mengetahui status data.

Jika Anda mencoba untuk mendapatkan hal-hal seperti Row Row atau data ringkasan lainnya di mana beberapa margin kesalahan dapat diterima, maka itu NOLOCKadalah cara yang baik untuk meningkatkan kinerja untuk kueri ini dan menghindarinya berdampak negatif terhadap kinerja database.

Selalu gunakan NOLOCKpetunjuk dengan sangat hati-hati dan memperlakukan data apa pun yang dikembalikan dengan mencurigakan.

tom.dietrich
sumber
Terima kasih. Inilah yang saya asumsikan tetapi dipertanyakan oleh seorang kolega dan penelitian awal saya membuat saya mempertanyakan diri saya sendiri. Dokumentasi SQLServer 2005 mengatakan bahwa dengan NOLOCK adalah skema penguncian default untuk semua pernyataan pilih! Kurasa petunjukku akan berlebihan ...
Bob Probst
2
... 2005 dan tidak berpengaruh apa pun. Kami menjalankan 2000 sekarang (terima kasih kepada vendor kami) dan tidak ada pernyataan serupa dalam dokumentasi.
Bob Probst
4
Teman Anda perlu membaca dokumentasi. Petunjuk Meja (Transact-SQL) msdn.microsoft.com/en-us/library/ms187373(SQL.90).aspx
Pittsburgh DBA
9
Catatan: jika ini benar, itu akan menjadi kekacauan mutlak.
Pittsburgh DBA
1
Poin 1 dan 2 harus dibatasi pada 1) "... ketika tindakan memasukkan / memperbarui / menghapus tertunda di atas meja ." dan 2) "... akan memungkinkan penyisipan / perbarui / hapus permintaan terhadap ...". Saya akan (preferensi pribadi) mengubah contoh "lebih cepat" menjadi "lebih cepat" karena perbedaannya menunggu proses lain selesai.
Ditebangi
61

NOLOCK membuat sebagian besar pernyataan SELECT lebih cepat, karena kurangnya kunci bersama. Juga, kurangnya penerbitan kunci berarti bahwa penulis tidak akan terhalang oleh SELECT Anda.

NOLOCK secara fungsional setara dengan tingkat isolasi dari READ UNCOMMITTED. Perbedaan utama adalah bahwa Anda dapat menggunakan NOLOCK pada beberapa tabel tetapi tidak pada yang lain, jika Anda mau. Jika Anda berencana untuk menggunakan NOLOCK pada semua tabel dalam kueri yang kompleks, maka menggunakan SET TINGKAT ISOLASI TRANSAKSI BACA TIDAK DIKOMPITASI lebih mudah, karena Anda tidak harus menerapkan petunjuk ke setiap tabel.

Berikut adalah informasi tentang semua tingkat isolasi yang Anda inginkan, serta petunjuk tabel.

SET TINGKAT ISOLASI TRANSAKSI

Petunjuk Tabel (Transact-SQL)

Pittsburgh DBA
sumber
2
Saya setuju, tetapi tidak sepenuhnya; penting untuk menunjukkan bahwa petunjuk NO LOCK / READ UNCOMMITTED tidak benar-benar meningkatkan kecepatan kueri, tetapi lebih-lebih membuatnya tampak lebih cepat karena tidak harus menunggu permintaan sebelumnya selesai. Jadi sungguh, query TAMPAK lebih cepat, daripada IS lebih cepat (saya pikir).
Möoz
1
@ BorhanMooz Yah, ada penghematan dari tidak harus meminta kunci dari manajer kunci. Bahkan jika tidak ada permintaan lain yang menunggu, ini memiliki biaya dan memori yang berlebihan.
Pittsburgh DBA
1
Saya sedang mendiskusikan ini dengan beberapa rekan kerja saya. Seperti yang saya pahami, permintaan menggunakan petunjuk WITH (NOLOCK) masih membutuhkan kunci Dibagi-Skema untuk dicapai ( mssqltips.com/sqlservertip/2470/… ).
Möoz
1
Ya, tetapi tidak ribuan kunci bersama di halaman atau luas. Kunci skema adalah SATU kunci, bukan RIBUAN. Jika kita ingin menjadi orang yang bertele-tele, kita dapat terus memperdebatkan ini, tetapi ya, akan ada jumlah overhead kunci yang minimal. Penghematan itu signifikan. Lakukan penghitungan
Pittsburgh DBA
6

Ini akan lebih cepat karena tidak harus menunggu kunci

Pelit
sumber
Seberapa cepat? Bisakah Anda memberikan angka peningkatan kecepatan?
Eugeniu Torica
5
"Berapa banyak" tergantung pada apa yang Anda lakukan secara spesifik dengan data Anda dan berapa lama biasanya Anda harus menunggu untuk mendapatkan kunci.
StingyJack
Satu-satunya tolok ukur yang benar adalah yang Anda buat & jalankan sendiri. Apa yang semua orang katakan kepada Anda sama baiknya dengan "cek ada di pos". Saya telah membuktikan banyak mitos dan anggapan yang salah berkali-kali dengan menjalankan tolok ukur saya sendiri.
TravisO
^ @TravisO - sepenuhnya benar. Saya telah menjalankan NOLOCK lebih lambat beberapa kali. Tidak sepenuhnya yakin mengapa, tapi saya menggunakannya saat pemecahan masalah dan saya tidak ingin (over) mempengaruhi produksi secara
negatif
2
  • Jawabannya adalah Ya jika kueri dijalankan beberapa kali sekaligus, karena setiap transaksi tidak perlu menunggu yang lain selesai. Namun, jika kueri dijalankan sekali sendiri maka jawabannya adalah Tidak.

  • Ya . Ada kemungkinan signifikan bahwa penggunaan DENGAN (NOLOCK) yang cermat akan mempercepat keseluruhan basis data Anda. Ini berarti bahwa transaksi lain tidak harus menunggu sampai pernyataan SELECT ini selesai, tetapi di sisi lain, transaksi lain akan melambat karena mereka sekarang berbagi waktu pemrosesan dengan transaksi baru.

Berhati-hatilah hanya menggunakan WITH (NOLOCK)pernyataan SELECT pada tabel yang memiliki indeks berkerumun.

WITH (NOLOCK) sering dieksploitasi sebagai cara ajaib untuk mempercepat transaksi baca database.

Rangkaian hasil dapat berisi baris yang belum dikomit, yang sering kali dibatalkan.

Jika WITH (NOLOCK) diterapkan ke tabel yang memiliki indeks non-clustered maka baris-indeks dapat diubah oleh transaksi lain karena data baris sedang dialirkan ke tabel hasil. Ini berarti bahwa set hasil dapat berupa baris yang hilang atau menampilkan baris yang sama beberapa kali.

READ COMMITTED menambahkan masalah tambahan di mana data rusak dalam satu kolom di mana banyak pengguna mengubah sel yang sama secara bersamaan.

WonderWorker
sumber