Mengapa SET ARITHABORT ON akan mempercepat permintaan secara dramatis?


75

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.

Jawaban:


62

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 ini, saya akhirnya menggunakan panduan rencana kueri (lihat ujung tautan) untuk memaksa rencana kueri yang saya inginkan.


3
Lebih dari enam tahun kemudian, tautan yang diberikan dalam jawaban ini masih "wajib dibaca" ... dan masih terkini, revisi terbaru adalah Desember '17.
takrl

30

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-Effects-Stored-Procedure-Performance. aspx untuk sedikit lebih banyak diskusi tentangnya.


Saya setuju dengan setengah dari jawaban ini. Saya sangat skeptis tentang klaim perhitungan numerik!
Martin Smith

2
@ Martin: Saya pikir saya tidak jelas. Saya baru saja mengatakan ARITHABORT ON membuat SQL Server akan error pada setiap div / 0 atau kesalahan aritmatika overflow. Ketika tidak aktif itu terus berjalan dan untuk alasan apa pun dapat menyebabkan semua jenis masalah mengerikan.

@ Ben - Ya maaf saya tidak ingin menyerang jawaban Anda, saya hanya menunjukkan bahwa akan sangat mudah untuk mengubah SETopsi mendapatkan rencana yang lebih baik dan salah mendiagnosis ini sebagai Opsi itu sendiri yang salah. Saya tidak yakin pria di tautan Anda belum melakukan ini.
Martin Smith

@ Martin - Tidak masalah, saya tidak berpikir Anda menyerang saya. Diskusi lain yang saya tautkan bisa sedikit tidak jelas. Saya hanya berusaha memberikan bukti pendukung.

@ Martin Dalam retrospeksi, saya yakin Anda benar.

21

Saya berpendapat bahwa ini hampir pasti parameter sniffing.

Sering dinyatakan bahwa SET OPTIONSdapat memengaruhi kinerja dengan cara ini, tetapi saya belum melihat satu sumber otoritatif untuk klaim ini kecuali untuk kasus di mana Anda menggunakan tampilan yang diindeks / kolom yang dihitung yang diindeks.

Dalam hal ini (untuk SQL2005 + dan kecuali database Anda dalam mode kompatibilitas SQL2000 ). Jika Anda memiliki keduanya ARITHABORTdan ANSI_WARNINGS OFFkemudian Anda akan menemukan indeks tidak digunakan sehingga mungkin memiliki scan daripada pencarian yang diinginkan (dan beberapa overhead karena hasil perhitungan tetap tidak dapat digunakan). ADO.NET tampaknya default untuk memiliki ANSI_WARNINGS ONdari tes cepat yang baru saja saya lakukan.

Klaim dalam jawaban Ben bahwa "cara server melakukan perhitungan numerik" dapat menambahkan menit ke hasil yang kalau tidak akan memakan waktu kurang dari sedetik sepertinya tidak masuk akal 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_ABORTopsi.

Tes cepat di jendela studio manajemen menunjukkan bahwa ketika SET ARITHABORT OFFdinyalakan dan permintaan 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 menjalankan kueri pengujian pertama dari aplikasi web kemudian dari studio manajemen dengan SET ARITHABORT OFFdan 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. Selain arithabortitu sendiri beberapa contoh lainnya adalah pengguna yang mengeksekusi memerlukan skema default yang sama (jika permintaan bergantung pada resolusi nama implisit) dan koneksi memerlukan languageset yang sama .

Daftar lengkap kunci cache rencana di sini


13

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

Menggunakan varian kueri Martin, saya mencari SP di cache prosedur dan menemukan dua di antaranya. Melihat rencana-rencananya, faktanya adalah seseorang memiliki ARITHABORT ON dan satunya memiliki ARITHABORT OFF. Versi ARITHABORT OFF 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 kembali secara instan. 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 di 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 di SSMS dengan rentang tanggal yang sempit dan mendapatkan 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 OFF ARITHABORT). Sekali lagi dari SSMS, kami menjalankan SP, kali ini dengan rentang tanggal lebar yang sama, dan melihat kinerja mengerikan yang sama dengan yang kami miliki dalam permintaan .NET asli.

Singkatnya, perbedaan itu tidak ada hubungannya dengan nilai sebenarnya dari ARITHABORT - dengan itu on atau off, 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 optimisasi kueri, pengujian kami mengonfirmasi bahwa Martin benar - penyebabnya adalah sniffing parameter dan rencana yang dihasilkan tidak optimal untuk semua rentang parameter.


1
Bertanya-tanya apa Setting ARITHABORT to OFF can negatively impact query optimization leading to performance issues.arti ungkapan itu . Apakah mereka hanya berbicara tentang ketidakmampuan untuk menggunakan indeks pada kolom dan tampilan yang dihitung (jika ANSI_WARNINGSjuga mati) atau jika memang memiliki beberapa efek lainnya.
Martin Smith

Saya tidak yakin. Saya bertanya-tanya apakah itu hanya kasus seseorang di MSDN mengalami situasi yang sama, mengatur ARTIHABORT ke ON, melihat peningkatan kinerja, dan melompat ke kesimpulan yang sama yang dimiliki orang lain. Sejauh tampilan yang diindeks dan kolom yang dihitung, saya tidak jelas. Pada satu titik ini menyatakan bahwa opsi SET harus memiliki nilai spesifik jika operasi INSERT, UPDATE, atau DELETE mengubah nilai data yang disimpan di dalamnya. Di tempat lain mereka menyatakan bahwa pengoptimal akan mengabaikan indeks untuk "permintaan apa pun" yang merujuk pada tampilan indeks atau kolom yang dihitung. Apakah keduanya benar, atau apakah itu benar-benar "data pengubah kueri"?
mdoyle

1

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

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 menemukan keduanya, dan tiket tersebut ditingkatkan ke tim PFE yang sangat senior, dan dua dukungan PFE berusaha 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 pembatasan izin dan memungkinkan pengguna dengan izin SELECT untuk menggunakan perintah ini. Perhatikan bahwa persyaratan berikut ada untuk izin SELECT yang 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.

masukkan deskripsi gambar di sini

Semoga pengalaman ini dapat membantu komunitas.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.