Database
 sql >> Teknologi Basis Data >  >> RDS >> Database

Tindak lanjut pada opsi kursor

Catatan:Posting ini awalnya diterbitkan hanya di eBook kami, High Performance Techniques for SQL Server, Volume 3. Anda dapat mengetahui tentang eBook kami di sini.

Lebih dari tiga tahun yang lalu, saya menulis posting tentang opsi kursor di SQL Server, dan mengapa Anda harus mengganti default:

  • Apa pengaruh opsi kursor yang berbeda?

Saya ingin memposting tindak lanjut untuk menegaskan kembali bahwa – meskipun Anda tidak boleh hanya menerima default – Anda benar-benar harus memikirkan opsi mana yang paling sesuai untuk skenario Anda. Saya juga ingin mengklarifikasi beberapa item yang muncul di komentar di postingan itu.

Andrew Kelly mengemukakan poin yang bagus, dan itu adalah STATIC kursor membuat salinan hasil satu kali, memasukkannya ke dalam tempdb, dan kemudian menghindari masalah konkurensi yang dapat memengaruhi DYNAMIC kursor. Satu opsi bukanlah pemenang yang jelas atas yang lain dalam semua kasus; misalnya, Anda mungkin memiliki banyak kursor (atau kursor dengan hasil yang sangat besar) dan/atau tempdb yang sudah terlalu terbebani dan tidak ingin menurunkan tekanan tambahan di sana. Tapi itu adalah sesuatu yang layak untuk diuji.

Fabiano juga mengemukakan poin bagus bahwa keduanya DYNAMIC dan FAST_FORWARD kursor bisa rentan terhadap masalah Hallowe'en (dibahas oleh Paul White dalam seri 4 bagian, mulai dari sini). Paul juga berkomentar bahwa FAST_FORWARD mungkin tidak rentan terhadap masalah, tergantung pada apakah pengoptimal memilih paket statis atau dinamis (Marc Friedman dari Microsoft menjelaskannya dengan sangat rinci di sini).

Akhirnya, saya ingin menunjukkan bahwa tidak semua kursor default dibuat sama. Saya menjalankan beberapa tes dan memeriksa bagaimana SQL Server memutuskan untuk mengatur opsi kursor di bawah berbagai skenario (divalidasi menggunakan sys.dm_exec_cursors fungsi manajemen dinamis). Kodenya cukup sederhana:

DECLARE c CURSOR FOR [...blah blah...];
SELECT properties FROM sys.dm_exec_cursors(@@SPID);

Berikut adalah hasil dari skenario yang saya uji:

Kueri kursor didasarkan pada… Ketik Konkurensi Cakupan
konstanta (FOR SELECT 1 atau FOR SELECT SYSDATETIME() ) Snapshot Hanya Baca Global
tabel #temp / ##temp Dinamis Optimis Global
tabel / tampilan pengguna Dinamis Optimis Global
tampilan katalog / DMV Snapshot Hanya Baca Global
gabung #tmp -> tabel / tampilan pengguna Dinamis Optimis Global
gabung #tmp -> tampilan katalog / DMV Snapshot Hanya Baca Global
gabung dengan tabel / tampilan pengguna -> tampilan katalog / DMV Snapshot Hanya Baca Global

Kredit yang jatuh tempo – investigasi ini dipicu oleh jawaban dari Jeroen Mostert di Stack Overflow.

Jadi Anda harus menyadari bahwa opsi default untuk kursor Anda, jika Anda tidak menimpanya, mungkin berbeda tergantung pada kueri yang mendasari kursor. Jika Anda mengharapkan perilaku tertentu dalam setiap atau semua kasus, biasakan untuk secara eksplisit menentukan opsi yang Anda inginkan.

Tapi sungguh, intinya adalah…

…berhenti menggunakan kursor. Benar-benar ada sedikit masalah hari ini di mana solusi terbaik adalah kursor, terutama jika Anda menggunakan SQL Server 2012 atau lebih baik - di mana hampir setiap masalah yang secara tradisional diselesaikan oleh kursor dapat diselesaikan menggunakan peningkatan fungsi jendela. Jika Anda masih merasa perlu menggunakan kursor, silakan ikuti saran di postingan ini dan pendahulunya untuk menentukan opsi mana yang harus Anda gunakan.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Menggunakan strace sebagai Alat Debugging DG40DBC di Linux

  2. Cara Memformat Tanggal di T-SQL

  3. Logging Minimal dengan INSERT…PILIH ke Tabel Cluster Kosong

  4. Lebih banyak peningkatan showplan? Ya silahkan!

  5. Pemetaan Kontrol Keamanan Lokal vs Penyedia Cloud Utama – Versi 4.0