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

Kejutan dan Asumsi Kinerja :SET NOCOUNT ON

Jika Anda pernah menggunakan Management Studio, pesan keluaran ini mungkin akan terlihat familier:

(1 baris terpengaruh)

Ini berasal dari DONE_IN_PROC SQL Server pesan, yang dikirim setelah penyelesaian pernyataan SQL yang berhasil (termasuk pengambilan rencana eksekusi, itulah sebabnya Anda melihat dua pesan ini saat Anda sebenarnya hanya menjalankan satu kueri).

Anda dapat menyembunyikan pesan-pesan ini dengan perintah berikut:

SET NOCOUNT ON;

Kenapa kamu ingin melakukan itu? Karena pesan ini cerewet dan sering tidak berguna . Dalam presentasi Kebiasaan Buruk dan Praktik Terbaik saya, saya sering berbicara tentang menambahkan SET NOCOUNT ON; ke semua prosedur tersimpan, dan mengaktifkannya dalam kode aplikasi yang mengirimkan kueri ad hoc. (Namun, selama proses debug, Anda mungkin ingin sebuah flag mengaktifkan kembali pesan, karena outputnya dapat berguna dalam kasus tersebut.)

Saya selalu menambahkan penafian bahwa saran untuk mengaktifkan opsi ini di mana-mana tidak universal; tergantung. Kumpulan rekaman ADO jadul sebenarnya menafsirkan ini sebagai kumpulan hasil, jadi menambahkannya ke kueri setelah fakta sebenarnya dapat merusak aplikasi yang sudah melewatkannya secara manual. Dan beberapa ORM (batuk NHibernate batuk ) sebenarnya mengurai hasil untuk menentukan keberhasilan perintah DML (ugh!). Silakan uji perubahan Anda.

Saya tahu bahwa pada satu titik saya telah membuktikan kepada diri saya sendiri bahwa pesan-pesan cerewet ini dapat memengaruhi kinerja, terutama melalui jaringan yang lambat. Tapi itu sudah lama sekali, dan minggu lalu Erin Stellato bertanya apakah saya pernah mendokumentasikannya secara resmi. Saya belum, jadi begini. Kami akan mengambil loop yang sangat sederhana, di mana kami akan memperbarui variabel tabel jutaan kali:

SET NOCOUNT OFF;
 
DECLARE @i INT = 1;
DECLARE @x TABLE(a INT);
INSERT @x(a) VALUES(1);
 
SELECT SYSDATETIME();
 
WHILE @i < 1000000
BEGIN
  UPDATE @x SET a = 1;
  SET @i += 1;
END
 
SELECT SYSDATETIME();

Beberapa hal yang mungkin Anda perhatikan:

  • Panel pesan dibanjiri dengan contoh (1 row(s) affected) pesan:

  • Inisial SELECT SYSDATETIME(); tidak muncul dengan sendirinya di panel hasil sampai setelah seluruh kumpulan selesai. Ini karena banjir.
  • Pengerjaan batch ini membutuhkan waktu sekitar 21 detik.

Sekarang, mari kita ulangi ini tanpa DONE_IN_PROC pesan, dengan mengubah SET NOCOUNT OFF; untuk SET NOCOUNT ON; dan jalankan lagi.

Meskipun panel pesan tidak lagi dibanjiri dengan baris pesan yang terpengaruh, batch masih membutuhkan waktu ~21 detik untuk dijalankan.

Kemudian saya berpikir, tunggu sebentar, saya tahu apa yang terjadi. Saya menggunakan mesin lokal, tanpa jaringan yang terlibat, menggunakan Memori Bersama, saya hanya memiliki SSD dan sekumpulan RAM…

Jadi saya mengulangi pengujian menggunakan salinan SSMS lokal saya terhadap Database Azure SQL jarak jauh – Standar, S0, V12. Kali ini, kueri membutuhkan waktu lebih lama, bahkan setelah mengurangi iterasi dari 1.000.000 menjadi 100.000. Tetapi sekali lagi tidak ada perbedaan nyata dalam kinerja apakah DONE_IN_PROC pesan sedang dikirim atau tidak. Kedua batch membutuhkan waktu sekitar 104 detik, dan ini dapat diulang dalam banyak iterasi.

Kesimpulan

Selama bertahun-tahun, saya telah beroperasi di bawah kesan bahwa SET NOCOUNT ON; adalah bagian penting dari setiap strategi kinerja. Ini didasarkan pada pengamatan yang saya lakukan, bisa dibilang, di era yang berbeda, dan kemungkinannya kecil untuk terwujud hari ini.

Karena itu, saya akan terus menggunakan SET NOCOUNT ON , meskipun pada perangkat keras saat ini tidak ada perbedaan kinerja yang mencolok. Saya masih merasa cukup kuat untuk meminimalkan lalu lintas jaringan jika memungkinkan. Saya harus mempertimbangkan untuk menerapkan tes di mana saya memiliki bandwidth yang jauh lebih terbatas (mungkin seseorang memiliki CD AOL yang dapat mereka pinjamkan kepada saya?), Atau memiliki mesin di mana jumlah memori lebih rendah dari batas buffer output Management Studio, untuk memastikan bahwa ada bukanlah dampak potensial dalam skenario terburuk. Sementara itu, meskipun mungkin tidak mengubah kinerja yang dirasakan tentang aplikasi Anda, mungkin masih membantu dompet Anda untuk selalu mengaktifkan opsi set ini, terutama dalam situasi seperti Azure – di mana Anda mungkin dikenai biaya untuk lalu lintas keluar.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jangan hanya membabi buta membuat indeks yang hilang itu!

  2. Memisahkan String:Sebuah Tindak Lanjut

  3. Sistem Email Otomatis untuk Mengirim Laporan Ringkasan Basis Data

  4. Membuat Cluster Docker Swarm di Azure Container Service

  5. Migrasi Django:Sebuah Primer