it-swarm.asia

Mengapa SET ARITHABORT ON akan mempercepat permintaan secara dramatis?

Kueri adalah pilihan tunggal yang mengandung banyak level pengelompokan dan operasi agregat. Dengan SET ARITHABORT ON membutuhkan waktu kurang dari satu detik, jika tidak maka akan membutuhkan beberapa menit. Kami telah melihat perilaku ini di SQL Server 2000 dan 2008.

79
Jonathan Allen

Sedikit tanggal, tetapi bagi siapa pun yang berakhir di sini dengan masalah yang sama ...

Saya memiliki masalah yang sama. Bagi saya itu ternyata menjadi parameter sniffing, yang pada awalnya saya tidak cukup mengerti untuk peduli. Saya menambahkan 'set arithabort on' yang memperbaiki masalah tetapi kemudian kembali. Lalu saya membaca:

http://www.sommarskog.se/query-plan-mysteries.html

Itu dibersihkan - semuanya - up. Karena saya menggunakan Linq ke SQL dan memiliki opsi terbatas untuk memperbaiki masalah, saya akhirnya menggunakan panduan rencana kueri (lihat ujung tautan) untuk memaksa rencana kueri yang saya inginkan.

63
Jason

Aplikasi .NET terhubung dengan opsi yang dinonaktifkan secara default, tetapi diaktifkan secara default di Management Studio. Hasilnya adalah server benar-benar melakukan cache 2 rencana eksekusi terpisah untuk sebagian besar/semua prosedur. Ini memengaruhi cara server melakukan perhitungan numerik dan karenanya Anda bisa mendapatkan hasil yang sangat berbeda tergantung pada prosedurnya. Ini benar-benar hanya satu dari 2 cara umum yang bisa dilakukan oleh seorang proc untuk mendapatkan rencana eksekusi yang mengerikan, yang lainnya adalah mengendus parameter.

Lihatlah https://web.archive.org/web/20150315031719/http://sqladvice.com/blogs/gstark/archive/2008/02/12/Arithabort-Option-Effect-Stored- Procedure-Performance.aspx untuk diskusi lebih lanjut tentang itu.

30
Ben Hoffman

Saya berpendapat bahwa ini hampir pasti parameter sniffing.

Sering dinyatakan bahwa SET OPTIONS dapat memengaruhi kinerja dengan cara ini, tetapi saya belum melihat satu pun sumber otoritatif untuk klaim ini kecuali untuk kasus di mana Anda menggunakan Tampilan indeks/kolom terkomputasi yang diindeks.

Dalam hal ini (untuk SQL2005 + dan kecuali database Anda dalam mode kompatibilitas SQL20 ). Jika Anda memiliki ARITHABORT dan ANSI_WARNINGSOFF maka Anda akan menemukan indeks tidak digunakan sehingga mungkin memiliki pemindaian daripada pencarian yang diinginkan (dan beberapa overhead karena hasil perhitungan tetap tidak dapat digunakan). ADO.NET tampaknya secara default memiliki ANSI_WARNINGS ON dari tes cepat yang baru saja saya lakukan.

Klaim dalam jawaban Ben bahwa "cara server melakukan perhitungan numerik" dapat menambahkan menit ke hasil yang akan memakan waktu kurang dari satu detik sepertinya tidak kredibel bagi saya. Saya pikir apa yang cenderung terjadi adalah bahwa setelah menyelidiki masalah kinerja kinerja Profiler digunakan untuk mengidentifikasi permintaan yang menyinggung. Ini disisipkan ke studio manajemen dan menjalankan dan mengembalikan hasil secara instan. Satu-satunya perbedaan yang jelas antara koneksi adalah ARITH_ABORT pilihan.

Tes cepat di jendela studio manajemen menunjukkan bahwa ketika SET ARITHABORT OFF dihidupkan dan kueri dijalankan bahwa masalah kinerja berulang sehingga ternyata kasus ditutup. Memang ini tampaknya merupakan metodologi pemecahan masalah yang digunakan dalam tautan Gregg Stark .

Namun itu mengabaikan fakta bahwa dengan set opsi yang Anda dapat akhirnya mendapatkan paket buruk yang sama persis dari cache .

Penggunaan kembali paket ini dapat terjadi bahkan jika Anda masuk sebagai pengguna yang berbeda dari penggunaan koneksi aplikasi.

Saya menguji ini dengan mengeksekusi kueri pengujian pertama dari aplikasi web kemudian dari studio manajemen dengan SET ARITHABORT OFF dan bisa melihat jumlah pengguna naik dari kueri di bawah ini.

SELECT usecounts, cacheobjtype, objtype, text ,query_plan
FROM sys.dm_exec_cached_plans 
CROSS APPLY sys.dm_exec_sql_text(plan_handle) 
CROSS APPLY sys.dm_exec_query_plan(plan_handle) 

Agar pembagian ini, pf rencana untuk benar-benar terjadi semua kunci cache rencana harus sama. Seperti halnya arithabort itu sendiri beberapa contoh lainnya adalah pengguna yang mengeksekusi memerlukan skema default yang sama (jika kueri bergantung pada resolusi nama implisit) dan koneksi memerlukan set language yang sama.

Daftar lengkap kunci cache rencana di sini

21
Martin Smith

Saya tahu saya terlambat ke pesta ini, tetapi untuk pengunjung masa depan, Martin benar. Kami mengalami masalah yang sama - sebuah SP berjalan sangat lambat untuk klien .NET, sementara itu sangat cepat untuk SSMS. Dalam mengeksplorasi dan menyelesaikan masalah, kami melakukan pengujian sistematis yang Kenny Evitt bertanya tentang komentarnya terhadap pertanyaan Martin.

Menggunakan varian dari kueri Martin, saya mencari SP dalam cache prosedur dan menemukan dua di antaranya. Melihat rencana-rencananya, sebenarnya ada kasus bahwa seseorang memiliki ARITHABORT ON dan satu memiliki MATI ARITHABORT Versi ARITHABORT MATI memiliki pencarian indeks sementara versi ARITHABORT ON menggunakan pemindaian indeks untuk output yang sama.Mengingat parameter yang terlibat, pencarian indeks akan membutuhkan pencarian pada puluhan juta catatan untuk output.

Saya membersihkan dua prosedur dari cache dan meminta klien .NET menjalankan SP lagi, menggunakan parameter yang sama (yang menampilkan rentang tanggal yang luas untuk pelanggan dengan banyak aktivitas). = SP dikembalikan seketika. Rencana cache menggunakan pemindaian indeks yang sama yang sebelumnya ditampilkan dalam rencana ARITHABORT ON - tetapi kali ini rencana untuk OFF ARITHABORT. Kami menjalankan SP dengan parameter yang sama dalam SSMS, dan kembali mendapatkan hasil secara instan Sekarang kita melihat bahwa rencana kedua di-cache, untuk ARITHABORT ON, dengan pemindaian indeks.

Kami kemudian membersihkan cache, menjalankan SP dalam SSMS dengan rentang tanggal yang sempit dan mendapat hasil instan. Kami menemukan bahwa rencana cache yang dihasilkan memiliki pencarian indeks, untuk output yang sama sebelumnya ditangani dengan pemindaian (yang juga merupakan pencarian dalam rencana asli dengan ARITHABORT OFF). Sekali lagi dari SSMS, kami menjalankan SP, kali ini dengan rentang tanggal yang sama lebar, dan melihat kinerja mengerikan yang sama yang kami miliki dalam permintaan .NET asli .

Singkatnya, perbedaan itu tidak ada hubungannya dengan nilai sebenarnya dari ARITHABORT - dengan itu hidup atau mati, dari salah satu klien, kita bisa mendapatkan kinerja yang dapat diterima atau mengerikan: Yang penting adalah nilai parameter yang digunakan dalam menyusun dan menyimpan rencana.

Sementara MSDN menunjukkan bahwa ARITHABORT OFF itu sendiri dapat memiliki dampak negatif pada pengoptimalan kueri, pengujian kami mengonfirmasi bahwa Martin benar - penyebabnya adalah sniffing parameter dan hasilnya rencana tidak optimal untuk semua rentang parameter.

13
mdoyle

Baru saja mengalami masalah ini. Seperti yang dikatakan orang di sini, akar penyebabnya adalah beberapa rencana kueri, salah satunya adalah kurang optimal. Saya hanya ingin memverifikasi bahwa ARITHABORT memang dapat menyebabkan masalah dengan sendirinya (karena permintaan saya mengalami masalah dengan tidak memiliki parameter, yang mengeluarkan parameter sniffing dari persamaan).

1
Alan D. Nelson

Ini mengingatkan saya pada masalah yang persis sama yang saya alami di sql server 2008 hari. Dalam kasus kami, kami tiba-tiba menemukan satu pekerjaan persegi tiba-tiba melambat (biasanya beberapa detik, dan sekarang 9+ menit), pekerjaan itu perlu mengakses server yang ditautkan, kami menambahkan set ARITHABORT pada langkah pekerjaan, dan sepertinya masalahnya dipecahkan selama beberapa hari dan kemudian dikembalikan.

Kami kemudian membuka tiket dengan dukungan MS, dan pada awalnya mereka tidak dapat menemukannya, dan tiket tersebut ditingkatkan ke tim PFE yang sangat senior, dan dua dukungan PFE mencoba untuk mencari tahu masalah ini.

Alasan terakhir adalah kredensial pengguna (untuk menjalankan langkah pekerjaan) tidak dapat mengakses statistik tabel yang mendasari (pada sisi server yang ditautkan), dan dengan demikian rencana eksekusi tidak dioptimalkan.

Secara detail, pengguna tidak memiliki izin pada DBCC SHOW_STATISTICS (meskipun pengguna dapat SELECT dari tabel). Menurut MSDN , aturan izin ini diubah setelah sql 2012 SP1

Izin untuk SQL Server dan Database SQL

Untuk melihat objek statistik, pengguna harus memiliki tabel atau pengguna harus menjadi anggota peran server tetap sysadmin, peran basis data tetap db_owner, atau peran basis data tetap db_ddladmin.

SQL Server 2012 SP1 memodifikasi batasan izin dan memungkinkan pengguna dengan izin SELECT untuk menggunakan perintah ini. Perhatikan bahwa persyaratan berikut ada untuk izin SELECT agar cukup untuk menjalankan perintah:

Untuk memverifikasi masalah ini, kita hanya perlu menjalankan profiler pada instance sisi server yang ditautkan dan menyalakan beberapa peristiwa di bagian "Kesalahan dan Peringatan" seperti yang ditunjukkan di bawah ini.

enter image description here

Semoga pengalaman ini dapat membantu komunitas.

1
jyao