SQL Server'daki tüm bağlantılar için ARITHABORT'u AÇIK duruma getirmenin sonuçları nelerdir?


10

Bu yüzden SQL Server'ımın düzensiz davranışının .Net SqlClient Data Provider'ın varsayılan ayarı nedeniyle olduğunu belirledim SET ARITHABORT OFF. Bununla birlikte, bunu uygulamanın en iyi yolunu tartışan çeşitli makaleler okudum. Benim için, sadece kolay bir yol istiyorum çünkü SQL Server acı çekiyor ve sorgu ayarım tamamen uygulama boyunca aşılmamış (ve açıkçası SETbir sp ekleyerek ÇALIŞMIYOR).

Erland Sommarskog'un konuyla ilgili parlak makalesinde , temel olarak uygulamayı SET ARITHABORT ONbağlantı için yayınlamak üzere değiştirerek güvenli yaklaşımı öneriyor . Ancak, dba.stackexchange sorusundan gelen bu cevapta Solomon Rutzky hem örnek hem de veritabanı çapında bir yaklaşım sunuyor.

Bu örneği tümüyle belirlerken burada hangi sonuçları kaçırıyorum? Gördüğüm gibi ... SSMS ONvarsayılan olarak bu kümeye sahip olduğundan , ONtüm bağlantılar için bu sunucu genelinde ayar yaparken herhangi bir zarar görmüyorum . Günün sonunda, her şeyden önce gerçekleştirmek için bu SQL Server'a ihtiyacım var.


Soruda bağlandığım cevabımın çoğunu okurken, artık varsayılan olarak KAPALI gibi görünüyor, bazı istemciler özellikle AÇIK durumda, ancak EF / SqlClient dokunmuyor, yani KAPALI olarak kalıyor.
Solomon Rutzky

1
EF yok, ancak EF'in örnek ayarını nasıl geçersiz kılabileceği konusunda ilginç bir noktaya değindiniz. Bu nedenle, bir bağlantı bunu geçersiz kılabilirse, bu kümeye sahip olmak için en güvenilir yer, mümkünse SQL Server'a kurulan bağlantıdan ...
Eric Swiggum

1
"Oturum açma oturumlarınızda ARITHABORT'u her zaman AÇIK olarak ayarlayın. ARITHABORT'u KAPALI olarak ayarlamak, sorgu optimizasyonunu olumsuz etkileyerek performans sorunlarına yol açabilir." microsoft'tan bu makale şöyle diyor: docs.microsoft.com/en-us/sql/t-sql/statements/…
Shiwangini Shishulkar

Çeşitli senaryoları test ettim, en son aldığım şey bu ayar ve parametre koklamanın yatak arkadaşları olmasıdır. Eğer varsa ARITHABORT OFF, o zaman iyi. Gelen tüm bağlantılar için kapalı tutun. (Bunu kontrol eden iyi şanslar). Ancak, bağlantı AÇIK olarak ayarlandığında bir bağlantı geldiğinde, SQL yeni bir Sorgu planı oluşturur ve bu performansı etkileyebilir. Alımım, örnek düzeyinde varsayılan kullanıcı seçeneği olarak AÇIK olarak ayarlayın ve sorguları buna göre ayarlayın.
Eric Swiggum

Yanıtlar:


11

Sadece var olan bazı temerrütler vardır, çünkü kimse onları değiştirmenin etkisinin ne olacağını gerçekten bilmiyor. Örneğin, işletim sistemi dili olarak "ABD İngilizcesi" kullanan bir sisteme yüklenirken varsayılan örnek düzeyi harmanlama SQL_Latin1_General_CP1_CI_AS. SQL_*Harmanlamaları SQL Server 2000 öncesi uyumluluk için olduğundan bu bir anlam ifade etmiyor . SQL Server 2000'de başlayan aslında Windows harmanlama seçebilir ve ABD ingilizce sistemleri için varsayılan böylece gerektiğini değiştirilmiştir Latin1_General_CI_AS. AMA, sanırım Microsoft'ta kimse çeşitli potansiyel alt sistemler ve sistem saklı yordamları vb. Üzerindeki etkisinin ne olacağını gerçekten bilmiyor.

Bu nedenle, bir veritabanı varsayılanı veya hatta örnek çapında ON olarak ayarlamanın herhangi bir olumsuz etkisinin farkında değilim. Aynı zamanda test etmedim. Ancak test etsem bile, uygulamanızla aynı kod yollarını kullanmayabilirim, bu yüzden bu gerçekten ortamınızda test etmeniz gereken bir şey. Olarak ayarlaONGeliştirici ve KG ortamlarınızdaki örnek düzeyinde ve bunun bir veya iki ay boyunca nasıl çalıştığını görün. Ardından Evreleme / UAT'de etkinleştirin. Her şey birkaç hafta boyunca iyi gitmeye devam ederse, bu yapılandırma değişikliğini Üretim olarak değiştirin. Anahtar, her gün vurulmayan çeşitli kod yollarını test etmek için mümkün olduğunca fazla zaman vermektir. Bazıları haftalık, aylık veya yıllık olarak vurulur. Bazı kod yolları yalnızca destekle, ya da yıllar önce birisinin yarattığı ve size hiç söylemediği ve sadece rastgele aralıklarla (nah, bu asla olmaz ;-)) kullanılan bazı geçici raporlar veya bakım işlemleri tarafından vurulur.

Bu yüzden, daha önce hiç değiştirmediğim için varsayılan "kullanıcı seçenekleri" ayarına sahip bir örnek üzerinde bazı testler yaptım.

Lütfen aklınızda bulundurun:

  • @@OPTIONS/ 'user options'bitmask değerdir
  • 64 bunun için biraz ARITHABORT ON

KURMAK

Hem SQLCMD (ODBC kullanan) hem de LINQPad (.NET SqlClient kullanan) ile test:

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 .

( ^DOS satır devam karakteridir; .son satırda sadece ekstra satırı kopyalayıp yapıştırmayı kolaylaştırmak için zorlamak gerekir)

LINQPad'de:

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());
  }
}

TEST 1: Öncesi

SQLCMD şunu döndürür:

master: 0 (ODBC)

LINQPad şunu döndürür:

tempdb: 0 (.Net SqlClient Data Provider)

VARSAYILAN BAĞLANTI SEÇENEĞİNİ DEĞİŞTİR:

Aşağıdaki T-SQL, ARITHABORTayarlanabilecek diğer seçenekleri kaldırmadan ARITHABORTve bitmasked değerinde önceden ayarlanmışsa hiçbir şeyi değiştirmeden etkinleştirir.

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;

TEST 2: Sonra

SQLCMD şunu döndürür:

master: 64 (ODBC)

LINQPad şunu döndürür:

tempdb: 64 (.Net SqlClient Data Provider)

Sonuç

Verilen:

  1. Sahip olmanın herhangi bir faydası yok gibi görünüyor ARITHABORT OFF
  2. Sahip olmanın faydası var ARITHABORT ON
  3. Varsayılan bağlantı ayarı (bağlantı tarafından geçersiz kılınmadıkça) = OFF
  4. ODBC veya OLEDB / .NET SqlClient'in ayarlamaya çalıştığı görünmüyor ARITHABORT, bu nedenle varsayılan ayarı kabul ediyorlar

Örnek çapında varsayılan bağlantı seçeneklerini değiştirmenizi öneririm (yukarıda gösterildiği gibi). Bu, uygulamayı güncellemekten daha az rahatsız edicidir. Sadece app güncelliyorduk eğer sen örneği çapında ayarı değiştirme ile ilgili bir sorun bulmak.

PS I değişen basit bir test yaptım tempdbve değil örneği çapında ayarı değiştirme ve işe görünmüyordu.


1
Huh, bu soru ve cevapları Paul White ile konuyla ilgili olarak okuduktan sonra SET ANSI_WARNINGS'i AÇIK duruma getirmenin dolaylı olarak ARITHABORT'u ON olarak ayarladığı anlaşılıyor. Ancak, ANSI_WARNINGS geçersiz kılsa bile, bağlantıda ARITHABORT OFF AYARLA da geçirilirse, garip planları seçerken olduğu gibi SQL sunucusu da ARITHABORT KAPALI gibi hareket eder. Bunu ... akıl almaz buluyorum. Şüphesiz, bunun bağlantıda ayarlanması gerekiyor VE ARITHABORT'u KAPALI duruma getiremiyor bile. Gözlerimde
dava

@EricSwiggum Bulduğunuz ilginç konu. Ancak, bu bilgilerden bağlantıda ayarlanması gerektiği sonucuna vardığınızı görmüyorum. Şu anda hiçbir şey geçersiz kılmıyorsa SET ARITHABORT OFF, bunun mevcut olmadığını biliyoruz . Öyleyse neden mevcut olduğu konusunda endişeleniyorsunuz? varsayılanın geçersiz kılındığı yerde gördüğümüz tek örnek SSMS'yi ON(bu iyi bir şeydir) olarak ayarlamaktır. Her iki durumda da, cevabımı testle ve en mantıklı öneri olarak gördüğüm şeyi (mevcut bilgi başına) güncelledim.
Solomon Rutzky

1
Kabul ediyorum, örnek çapında ayarı varsayılan olarak etkinleştirin. Ancak sonuçta bağlantı neyin ayarlandığını kontrol eder. Çeşitli teknolojilerin / protokollerin SQL'e bağlandığı paylaşılan durumlar ne olacak? Yani, etrafta koşup deli bir adam gibi gelişime "ARITHABORT ON SET" diye bağırmam gerekiyor mu? ya da en azından, eğer mümkünse, ARITHABORT KAPALI'nın bulunmadığını tanıtın .. Ayrıca, şimdiye kadar 6 yaşımın tam zamanlı bir DBA olarak başa gelmediğini görmek de garip geliyor. ya da belki de yeterince sert bakmadığım bir durumdur. Beni yedekle Paul ya da Erland, LOL, bunun nesi var?
Eric Swiggum

@EricSwiggum 1) Örnek düzeyi varsayılanını değiştirirseniz, hiçbir şey bağırıp dolaşmak zorunda kalmazsınız. 2) Sadece yokluğunu teşvik etmek gerekir ARITHABORT OFF eğer bunun hiçbirini gerçek incidences bulabilirsiniz. Şimdiye kadar hiç yoktur. 3) Bu sorgu planlarını etkilediğinden, tabloların SQL Server'ın dikkate alınması gereken belirli seçeneklere sahip olmasına neden olacak yeterli veriye sahip olmaması, şimdi daha fazla seçenek olduğu ve bazılarının kötü olduğu olabilir. Ya da belki de güncel olmayan istatistikler gibi başka geçici faktörler de vardır. Tam olarak emin değilim.
Solomon Rutzky

@EricSwiggum Orada seninle aynı fikirde değilim. Bunun cevabımın başında bahsettiğim şeye çok benzediğini düşünüyorum (yani ABD İngilizcesi sistemleri için varsayılan harmanlama): Microsoft'un eski sistemlerin yükseltme sonrasında hatalar alma korkusu (yani geriye dönük uyumluluk garantisi) aslında olduğundan daha fazla zarar veriyor ideal olmayan senaryonun kurulum tabanını / kapsamını artırır. Bu, geçmişte kalmak için gittikçe artan bir çekme ve işlerin daha da iyileşme şansının azalmasını sağlar. Bunlar, bant yardımını sökmenin ve acıyı şimdi atlatmanın daha iyi olduğu durumlardır.
Solomon Rutzky
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.