Sqlserver
 sql >> Teknologi Basis Data >  >> RDS >> Sqlserver

Menghindari kebuntuan SQL dengan penyetelan kueri:Saran dari Brent Ozar

Sebagai bagian dari Seri Musim Gugur Hari Pelatihan Database Quest, Brent Ozar, Master Bersertifikat Microsoft mempresentasikan tutorial tentang “Menghindari Kebuntuan dengan Penyetelan Kueri”. Program ini berfokus pada tiga masalah konkurensi yang terjadi di SQL Server, tiga cara untuk memperbaikinya, dan satu cara yang tampaknya memperbaikinya, tetapi sebenarnya tidak.

Masalah konkurensi:Mengunci, memblokir, dan kebuntuan di SQL Server

Apa itu masalah konkurensi? Itu terjadi ketika kueri mencoba menghindari konflik satu sama lain atas objek database seperti tabel. Mereka adalah:

  • Mengunci – Kueri melakukan ini sepanjang waktu untuk mencegah kueri lain menggunakan tabel secara bersamaan. Ini adalah operasi basis data normal.
  • Memblokir  – Ini terjadi ketika satu kueri memiliki kunci normal, tetapi kueri lain mencoba mendapatkan kunci yang sama. Kueri kedua harus menunggu selama yang diperlukan agar kueri pertama melepaskan kunci. Bergantung pada sifat kueri pertama, kueri kedua bisa menunggu dalam waktu yang sangat singkat atau sangat lama. Penantian panjang itulah yang benar-benar memengaruhi kinerja.
  • Kebuntuan – Deadlock terjadi saat satu kueri mengambil kunci, kueri lain mengambil kunci yang berbeda, dan kemudian masing-masing ingin mendapatkan kunci lainnya. SQL Server menyelesaikan ini dengan menetapkan salah satu kueri sebagai korban dan membunuhnya untuk memecahkan kebuntuan. Meskipun salah satu kueri dapat dilanjutkan, hal ini juga berdampak pada performa.

Memperbaiki masalah konkurensi

Terlepas dari apakah Anda mengalami blok atau kebuntuan di SQL Server, ada beberapa cara untuk memperbaiki masalah konkurensi. Brent mempresentasikan tiga metode ini, dan menghabiskan sebagian besar sisa sesi dengan fokus pada yang kedua – memperbaiki kode yang buruk.

  1. Memiliki cukup indeks untuk membuat kueri Anda cepat, tetapi tidak terlalu banyak sehingga memperlambat segalanya dengan membuat kueri menahan lebih banyak kunci untuk waktu yang lebih lama
  2. Sesuaikan kode transaksi Anda sehingga kueri bekerja melalui tabel dalam urutan yang dapat diprediksi yang sama setiap kali
  3. Gunakan tingkat isolasi yang tepat untuk kebutuhan aplikasi Anda

Saat dia terjun ke bagian program, Brent berkomentar tentang penggunaan pernyataan NOLOCK untuk memblokir dan menemui jalan buntu. Dia memperingatkan bahwa NOLOCK tidak benar-benar memperbaiki masalah ini karena bergantung pada "pembacaan kotor" – pada dasarnya, itu mengabaikan kunci baris kueri lainnya.

Dalam demonstrasinya menggunakan database Stack Overflow, dia membuat kueri sederhana yang mencari dan menghitung orang bernama "Alex." Kemudian, dia membuat kueri lain yang akan menjalankan pembaruan pada orang yang tidak bernama Alex—tidak ada penyisipan atau penghapusan catatan. Satu permintaan seharusnya tidak ada hubungannya dengan yang lain. Tapi, menjalankannya bersama-sama menghasilkan hasil yang berbeda dalam jumlah orang bernama Alex. Ini karena NOLOCK memungkinkan Anda melihat data yang tidak dikomit, yang mengarah ke hasil acak yang tidak dapat Anda prediksi. Itu hanya terjadi di bawah konkurensi.

Jelas, perbaikan yang lebih baik diperlukan untuk pemblokiran dan kebuntuan di SQL Server yang tidak mengarah ke hasil yang acak dan tidak terduga.

Solusi yang lebih baik untuk SQL deadlock

Brent kemudian mendemonstrasikan cara memperbaiki kebuntuan dengan mengubah kode yang menyebabkannya. Demo pertamanya menunjukkan situasi sederhana yang melibatkan dua meja sehingga penonton bisa melihat kebuntuan dalam gerakan lambat saat itu terjadi. Karena SQL Server mencari jalan buntu setiap 5 detik dan mematikan kueri yang paling mudah dikembalikan, kami dapat melihat korban kebuntuan muncul.

Dalam situasi sederhana, saran paling umum berlaku, dan itu adalah menyentuh tabel dalam urutan yang sama setiap kali membuat kueri. Ini biasanya akan menjaga kueri agar tidak menemui jalan buntu.

Bagaimana dengan kueri yang lebih kompleks? Untuk skenario ini, Brent menggunakan situasi yang lebih realistis yang dapat dengan mudah muncul di Stack Overflow di mana dua orang saling menjawab pertanyaan satu sama lain. Karena pengguna yang sama terlibat dalam kedua transaksi, ini menyebabkan kebuntuan.

Di sini, tidak cukup untuk mengerjakan setiap tabel dalam urutan yang sama setiap kali, tetapi juga perlu meminimalkan berapa kali setiap meja disentuh. Seperti yang dijelaskan Brent, perbaikannya dapat melibatkan beberapa kode jelek yang menyebabkan kueri diblokir, tetapi setidaknya tidak menemui jalan buntu. Dalam hal ini, blok durasi pendek yang memungkinkan kedua kueri berjalan hingga selesai lebih baik daripada kebuntuan yang menghentikan salah satunya.

Tidak ada yang ingin mengubah kode dalam ratusan kueri, jadi fokuslah pada kueri yang terus menemui jalan buntu, hapus baris yang tidak perlu dari transaksi, dan jangan takut untuk memasukkan blok untuk menghindari kebuntuan.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. SQL Server v.Berikutnya :Performa STRING_AGG, Bagian 2

  2. Bagaimana cara mengubah gambar ke array byte menggunakan javascript hanya untuk menyimpan gambar di server sql?

  3. Kueri membandingkan tanggal dalam SQL

  4. Buat Fungsi Bernilai Tabel Multi-Pernyataan (MSTVF) di SQL Server

  5. Apa cara tercepat untuk menyisipkan banyak data secara massal di SQL Server (klien C#)