Apa konsekuensi dari pengaturan ARITHABORT ON untuk semua koneksi di SQL Server?

10

Jadi saya telah menentukan bahwa perilaku tidak menentu dari SQL Server saya adalah karena pengaturan default SET ARITHABORT OFF. Net SqlClient Data Provider . Dengan demikian, saya telah membaca berbagai artikel yang memperdebatkan cara terbaik untuk mengimplementasikannya. Bagi saya, saya hanya ingin cara yang mudah karena SQL Server menderita dan penyetelan kueri saya belum sepenuhnya transenden di seluruh aplikasi (dan jelas menambahkan SETdalam sp A TIDAK BEKERJA).

Dalam artikel brilian Erland Sommarskog tentang topik tersebut, ia pada dasarnya menyarankan untuk mengambil pendekatan yang aman dengan mengubah aplikasi untuk mengeluarkan SET ARITHABORT ONuntuk koneksi. Namun, dalam jawaban ini dari pertanyaan dba.stackexchange , Solomon Rutzky menawarkan pendekatan instans luas dan di seluruh basis data.

Konsekuensi apa yang saya lewatkan di sini dengan mengatur seluruh instance ini? Seperti yang saya lihat ... karena SSMS telah menetapkan ini ONsecara default, saya tidak melihat ada salahnya mengatur seluruh ONserver ini untuk semua koneksi. Pada akhirnya, saya hanya perlu SQL Server ini untuk melakukan di atas segalanya.

Eric Swiggum
sumber
Membaca sebagian dari jawaban saya yang Anda tautkan dalam pertanyaan, sekarang tampaknya sudah MATI secara default, beberapa klien secara khusus AKTIFKAN, tetapi EF / SqlClient tidak menyentuhnya, yang artinya tetap sebagai MATI.
Solomon Rutzky
1
Tidak ada EF, tetapi Anda meningkatkan poin menarik dengan bagaimana EF dapat mengesampingkan pengaturan seluruh instance. Jadi, jika koneksi dapat mengesampingkan ini, jelas tempat yang paling dapat diandalkan untuk memiliki set ini adalah dari dalam koneksi yang dibuat ke SQL Server, jika memungkinkan ...
Eric Swiggum
1
"Selalu atur ARITHABORT ke ON di sesi masuk Anda. Mengatur ARITHABORT ke OFF dapat berdampak negatif pada optimasi kueri, yang mengarah ke masalah kinerja." artikel dari microsoft ini mengatakan: docs.microsoft.com/en-us/sql/t-sql/statements/…
Shiwangini Shishulkar
Saya telah menguji berbagai skenario, pengambilan terakhir saya dari semua adalah bahwa pengaturan dan parameter sniffing ini adalah teman baik. Jika sudah ARITHABORT OFF, maka baiklah. Matikan untuk semua koneksi yang masuk. (Semoga berhasil mengendalikan itu). Tetapi ketika koneksi datang dengan itu diatur ke ON, maka SQL menghasilkan rencana Query baru dan ini dapat mempengaruhi kinerja. Ambillah, setel ON sebagai opsi pengguna default di tingkat instance dan sesuaikan kueri.
Eric Swiggum

Jawaban:

11

Ada beberapa default yang ada hanya karena tidak ada yang benar-benar tahu apa efek mengubahnya. Misalnya, susunan level instance default ketika menginstal pada sistem yang menggunakan "Bahasa Inggris AS" sebagai bahasa OS SQL_Latin1_General_CP1_CI_AS. Ini tidak masuk akal karena SQL_*pemeriksaan untuk kompatibilitas pra-SQL Server 2000. Mulai di SQL Server 2000 Anda benar-benar dapat memilih Windows collation, dan default untuk sistem bahasa Inggris AS seharusnya diubah menjadi Latin1_General_CI_AS. TETAPI, saya kira tidak ada seorang pun di Microsoft yang benar-benar tahu apa dampaknya bagi semua sub-sistem potensial dan prosedur tersimpan sistem, dll.

Jadi, saya tidak mengetahui adanya dampak negatif spesifik dari pengaturan ke ON baik sebagai default database atau bahkan instance-wide. Pada saat yang sama, saya belum mengujinya. Tetapi bahkan jika saya telah mengujinya, saya mungkin masih tidak menggunakan jalur kode yang sama dengan aplikasi Anda, jadi ini adalah sesuatu yang benar-benar perlu Anda uji di lingkungan Anda. Setel keONpada tingkat contoh di lingkungan Dev dan QA Anda dan lihat cara kerjanya selama satu atau dua bulan. Kemudian aktifkan di Staging / UAT. Jika semua terus berjalan dengan baik selama beberapa minggu, gulung perubahan konfigurasi itu ke Produksi. Kuncinya adalah memberi waktu sebanyak mungkin untuk menguji berbagai jalur kode yang tidak mengenai setiap hari. Beberapa hit mingguan atau bulan atau tahunan. Beberapa jalur kode hanya dihantam oleh dukungan, atau beberapa laporan ad hoc atau pemeliharaan yang dibuat seseorang bertahun-tahun yang lalu dan tidak pernah memberi tahu Anda tentang dan hanya digunakan secara berkala (nah, itu tidak pernah terjadi ;-).

Jadi, saya melakukan beberapa pengujian pada contoh yang masih memiliki pengaturan "opsi pengguna" default karena saya tidak pernah mengubahnya.

Tolong dicatat:

  • @@OPTIONS/ 'user options'adalah nilai bitmasked
  • 64 adalah bit untuk ARITHABORT ON

MEMPERSIAPKAN

Saya diuji dengan SQLCMD (yang menggunakan ODBC) dan LINQPad (yang menggunakan .NET SqlClient):

SQLCMD -W -S (local) ^
-Q"SELECT CONCAT(DB_NAME(), N': ', @@OPTIONS & 64, N' (', ses.[client_interface_name], N')') FROM sys.dm_exec_sessions ses WHERE ses.[session_id] = @@SPID;"
echo .

( ^ini adalah karakter kelanjutan garis DOS; .baris terakhir hanya untuk memaksa garis tambahan agar lebih mudah untuk menyalin dan menempel)

Di LINQPad:

using (SqlConnection connection =
    new SqlConnection(@"Server=(local);Trusted_Connection=true;Database=tempdb;"))
{
  using (SqlCommand command = connection.CreateCommand())
  {
    command.CommandText = @"SELECT @RetVal =
CONCAT(DB_NAME(), N': ', @@OPTIONS & 64, N' (', ses.[client_interface_name], N')')
FROM  sys.dm_exec_sessions ses
WHERE ses.[session_id] = @@SPID;";
    SqlParameter paramRetVal = new SqlParameter("@RetVal", SqlDbType.NVarChar, 500);
    paramRetVal.Direction = ParameterDirection.Output;
    command.Parameters.Add(paramRetVal);

    connection.Open();
    command.ExecuteNonQuery();

    Console.WriteLine(paramRetVal.Value.ToString());
  }
}

UJI 1: Sebelumnya

SQLCMD kembali:

master: 0 (ODBC)

LINQPad kembali:

tempdb: 0 (.Net SqlClient Data Provider)

MENGUBAH OPSI KONEKSI DEFAULT:

T-SQL berikut ini memungkinkan ARITHABORTtanpa menghapus opsi lain yang mungkin diatur, dan tanpa mengubah apa pun jika ARITHABORTsudah ditetapkan dalam nilai bitmasked.

DECLARE @UserOptions INT;

-- Get current bitmasked value and ensure ARITHABORT is enabled:
SELECT @UserOptions = CONVERT(INT, cnf.[value_in_use]) | 64 -- enable "ARITHABORT"
FROM   sys.configurations cnf
WHERE  cnf.[configuration_id] = 1534 -- user options

-- Apply new default connection options:
EXEC sys.sp_configure N'user options', @UserOptions;
RECONFIGURE;

UJI 2: Setelah

SQLCMD kembali:

master: 64 (ODBC)

LINQPad kembali:

tempdb: 64 (.Net SqlClient Data Provider)

Kesimpulan

Mengingat bahwa:

  1. Tampaknya tidak ada manfaatnya memiliki ARITHABORT OFF
  2. Ada untungnya memiliki ARITHABORT ON
  3. Pengaturan koneksi default (kecuali diganti oleh koneksi) = OFF
  4. Tampaknya ODBC atau OLEDB / .NET SqlClient tidak mencoba untuk mengatur ARITHABORT, sehingga mereka menerima pengaturan default

Saya akan menyarankan mengubah opsi koneksi standar instans-lebar (seperti yang ditunjukkan di atas). Ini akan kurang menonjol daripada memperbarui aplikasi. Saya hanya akan memperbarui aplikasi jika Anda menemukan masalah dengan mengubah pengaturan lebar-instance.

PS Saya melakukan tes sederhana dengan mengubah tempdbdan tidak mengubah pengaturan lebar-instance dan sepertinya tidak berhasil.

Solomon Rutzky
sumber
1
Huh, setelah membaca T&J ini dengan Paul White tentang masalah ini, tampak bahwa melewati SET ANSI_WARNINGS ON, secara implisit menetapkan ARITHABORT ke ON. NAMUN, jika SET ARITHABORT OFF juga lulus dalam koneksi, bahkan dengan ANSI_WARNINGS menimpanya, SQL server masih akan "bertindak" seperti ARITHABORT OFF, seperti dalam memilih paket aneh. Saya menemukan ini ... membingungkan. Jadi tanpa ragu, ini perlu diatur dalam koneksi DAN SET OFF ARITHABORT bahkan tidak bisa ada.
Kasing
@EricSwiggum Thread menarik yang Anda temukan. Namun, saya tidak melihat bagaimana Anda menyimpulkan dari info yang perlu diatur dalam koneksi. Jika tidak ada saat utama itu, maka kita tahu bahwa SET ARITHABORT OFFini tidak hadir. Jadi mengapa khawatir hal itu hadir? satu-satunya contoh kita telah melihat di mana default ditimpa adalah pengaturan SSMS ke ON(yang merupakan hal yang baik). Either way, saya telah memperbarui jawaban saya dengan pengujian dan apa yang saya lihat sebagai rekomendasi paling logis (per info yang ada).
Solomon Rutzky
1
Saya setuju, aktifkan pengaturan lebar instance sebagai default. Tetapi pada akhirnya koneksi mengontrol apa yang diatur. Bagaimana dengan kasus instance bersama di mana berbagai teknologi / protokol terhubung ke SQL? Maksud saya, apakah saya harus berlari dan berteriak "SET ARITHABORT ON" untuk pengembangan seperti orang gila? atau paling tidak, mempromosikan tidak adanya ARITHABORT OFF jika memungkinkan .. Saya juga merasa aneh bahwa saya belum pernah melihat ini menjadi masalah sampai sekarang, tahun ke-6 saya sebagai DBA penuh waktu. atau mungkin itu adalah kasus di mana saya belum melihatnya dengan cukup keras. Dukung aku Paul atau Erland, LOL, ada apa dengan ini?
Eric Swiggum
@EricSwiggum 1) Anda tidak perlu berlarian berteriak apa pun jika Anda mengubah standar tingkat instance. 2) Anda hanya perlu mempromosikan ketidakhadiran ARITHABORT OFF jika Anda menemukan insiden aktualnya. Sejauh ini kemungkinan tidak ada. 3) Karena ini mempengaruhi rencana kueri, bisa jadi tabel tidak pernah memiliki cukup data untuk menyebabkan SQL Server untuk memiliki pilihan tertentu untuk dipertimbangkan, di mana sekarang ada lebih banyak pilihan, dan beberapa buruk. Atau mungkin ada faktor sementara lainnya, seperti statistik yang ketinggalan zaman, dll. Tidak sepenuhnya yakin.
Solomon Rutzky
@EricSwiggum, saya tidak setuju dengan Anda di sana. Saya pikir ini sangat mirip dengan apa yang saya sebutkan di awal jawaban saya (yaitu susunan standar untuk sistem bahasa Inggris AS): Ketakutan Microsoft terhadap sistem lama mendapatkan kesalahan saat memutakhirkan (yaitu jaminan kompatibilitas ke belakang) tidak lebih berbahaya daripada baiknya seperti yang sebenarnya meningkatkan install-base / lingkup skenario yang tidak ideal. Ini membuatnya menjadi daya tarik yang semakin meningkat untuk tetap berada di masa lalu, dan kesempatan yang semakin berkurang untuk menjadi lebih baik. Ini adalah kasus di mana lebih baik untuk merobek bantuan band dan hanya menyelesaikan rasa sakit dengan sekarang.
Solomon Rutzky