Sự phân nhánh của cài đặt ARITHABORT ON cho tất cả các kết nối trong SQL Server là gì?


10

Vì vậy, tôi đã xác định rằng hoạt động thất thường của Máy chủ SQL của mình là do cài đặt mặc định của Nhà cung cấp dữ liệu .Net SqlClient SET ARITHABORT OFF. Như đã nói, tôi đã đọc nhiều bài viết tranh luận về cách tốt nhất để thực hiện điều này. Đối với tôi, tôi chỉ muốn một cách dễ dàng vì SQL Server đang bị ảnh hưởng và việc điều chỉnh truy vấn của tôi chưa hoàn toàn vượt qua ứng dụng (và rõ ràng là thêm SETvào một sp KHÔNG LÀM VIỆC).

Trong bài viết xuất sắc của Erland Sommarskog về chủ đề này, về cơ bản, ông đề nghị thực hiện phương pháp an toàn bằng cách thay đổi ứng dụng để phát hành SET ARITHABORT ONkết nối. Tuy nhiên, trong câu trả lời này từ câu hỏi dba.stackexchange , Solomon Rutzky cung cấp cả cách tiếp cận trên toàn bộ cơ sở dữ liệu và toàn bộ cơ sở dữ liệu.

Tôi đang thiếu những phân nhánh nào ở đây với cài đặt toàn thể này? Theo tôi thấy ... vì SSMS có cài đặt này ONtheo mặc định, tôi thấy không có hại gì khi đặt toàn bộ ONmáy chủ này cho tất cả các kết nối. Vào cuối ngày, tôi chỉ cần SQL Server này để thực hiện trên tất cả các thứ khác.


Đọc qua nhiều câu trả lời của tôi mà bạn đã liên kết trong câu hỏi, có vẻ như nó bị TẮT theo mặc định, một số khách hàng đặc biệt bật nó lên, nhưng EF / SqlClient không chạm vào nó, điều đó có nghĩa là nó vẫn TẮT.
Solomon Rutzky

1
Không có EF, nhưng bạn nêu lên một điểm thú vị với cách EF có thể ghi đè cài đặt toàn thể hiện. Vì vậy, nếu một kết nối có thể ghi đè lên điều này, rõ ràng nơi đáng tin cậy nhất để có bộ này là từ bên trong kết nối được thiết lập cho SQL Server, nếu có thể ...
Eric Swiggum

1
"Luôn đặt ARITHABORT thành BẬT trong các phiên đăng nhập của bạn. Đặt ARITHABORT thành TẮT có thể tác động tiêu cực đến tối ưu hóa truy vấn, dẫn đến các vấn đề về hiệu suất." bài viết này từ microsoft nói: docs.microsoft.com/en-us/sql/t-sql/statements/ Kẻ
Shiwangini Shishulkar

Tôi đã thử nghiệm nhiều kịch bản khác nhau, điểm cuối cùng của tôi là cài đặt và thông số đánh hơi này là đầu giường. Nếu bạn có ARITHABORT OFF, thì tốt thôi. Giữ nó cho tất cả các kết nối đến. (Chúc may mắn kiểm soát điều đó). Nhưng khi một kết nối đi kèm với nó được đặt thành BẬT, thì SQL sẽ tạo ra một kế hoạch Truy vấn mới và điều này có thể ảnh hưởng đến hiệu suất. Tôi thực hiện, đặt BẬT làm tùy chọn người dùng mặc định ở cấp độ cá thể và điều chỉnh các truy vấn phù hợp.
Eric Swiggum

Câu trả lời:


11

Có một số mặc định tồn tại chỉ vì không ai thực sự biết tác động của việc thay đổi chúng sẽ là gì. Ví dụ: đối chiếu mức cá thể mặc định khi cài đặt trên hệ thống sử dụng "Tiếng Anh Mỹ" làm ngôn ngữ HĐH SQL_Latin1_General_CP1_CI_AS. Điều này không có ý nghĩa gì vì các bộ SQL_*sưu tập dành cho khả năng tương thích trước SQL Server 2000. Bắt đầu từ SQL Server 2000 bạn thực sự có thể chọn một collation Windows, và vì vậy mặc định cho hệ thống tiếng Anh Mỹ nên đã được thay đổi để Latin1_General_CI_AS. NHƯNG, tôi đoán không ai ở Microsoft thực sự biết tác động sẽ ra sao đối với tất cả các hệ thống phụ và quy trình lưu trữ hệ thống tiềm năng khác nhau, v.v.

Vì vậy, tôi không nhận thức được bất kỳ tác động tiêu cực cụ thể nào của việc đặt nó thành BẬT làm cơ sở dữ liệu mặc định hoặc thậm chí toàn thể hiện. Đồng thời, tôi đã không kiểm tra nó. Nhưng ngay cả khi tôi đã kiểm tra nó, tôi vẫn có thể không sử dụng các đường dẫn mã giống như ứng dụng của bạn, vì vậy đây là thứ mà bạn thực sự cần kiểm tra trong môi trường của mình. Đặt nó thànhONở cấp độ cá thể trong môi trường Dev và QA của bạn và xem cách nó hoạt động trong một hoặc hai tháng. Sau đó kích hoạt nó trong Staging / UAT. Nếu tất cả tiếp tục diễn ra tốt đẹp trong vài tuần, hãy thay đổi cấu hình đó thành Sản xuất. Điều quan trọng là cung cấp càng nhiều thời gian càng tốt để kiểm tra các đường dẫn mã khác nhau không bị tấn công hàng ngày. Một số được đánh hàng tuần hoặc hàng tháng hoặc hàng năm. Một số đường dẫn mã chỉ được hỗ trợ, hoặc một số báo cáo đột xuất hoặc bảo trì mà ai đó đã tạo ra cách đây nhiều năm và không bao giờ nói với bạn về và chỉ được sử dụng trong các khoảng thời gian ngẫu nhiên (nah, điều đó không bao giờ xảy ra ;-).

Vì vậy, tôi đã thực hiện một số thử nghiệm trên một phiên bản vẫn có cài đặt "tùy chọn người dùng" mặc định vì tôi chưa bao giờ thay đổi nó.

Xin lưu ý:

  • @@OPTIONS/ 'user options'là một giá trị bitmasked
  • 64 là bit cho ARITHABORT ON

THIẾT LẬP

Tôi đã thử nghiệm với cả SQLCMD (sử dụng ODBC) và LINQPad (sử dụng .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 .

( ^ký tự tiếp tục dòng DOS; .trên dòng cuối cùng chỉ là buộc dòng phụ để dễ sao chép và dán hơn)

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

KIỂM TRA 1: Trước

Trả về SQLCMD:

master: 0 (ODBC)

LINQPad trả về:

tempdb: 0 (.Net SqlClient Data Provider)

THAY ĐỔI TÙY CHỌN LIÊN KẾT:

T-SQL sau đây cho phép ARITHABORTmà không xóa bất kỳ tùy chọn nào khác có thể được đặt và không thay đổi bất cứ điều gì nếu ARITHABORTđã được đặt trong giá trị 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;

KIỂM TRA 2: Sau

Trả về SQLCMD:

master: 64 (ODBC)

LINQPad trả về:

tempdb: 64 (.Net SqlClient Data Provider)

Phần kết luận

Cho rằng:

  1. Dường như không có bất kỳ lợi ích nào khi có ARITHABORT OFF
  2. Có lợi ích khi có ARITHABORT ON
  3. Cài đặt kết nối mặc định (trừ khi bị ghi đè bởi kết nối) = OFF
  4. Dường như ODBC hoặc OLEDB / .NET SqlClient cố gắng đặt ARITHABORT, do đó họ chấp nhận cài đặt mặc định

Tôi sẽ đề nghị thay đổi các tùy chọn kết nối mặc định trên toàn thể hiện (như được hiển thị ở trên). Điều này sẽ ít gây khó chịu hơn so với việc cập nhật ứng dụng. Tôi sẽ chỉ cập nhật ứng dụng nếu bạn thấy có vấn đề với việc thay đổi cài đặt toàn thể hiện.

PS Tôi đã thực hiện một thử nghiệm đơn giản với việc thay đổi tempdbkhông thay đổi cài đặt toàn thể hiện và nó dường như không hoạt động.


1
Huh, sau khi đọc câu hỏi và trả lời này với Paul White về chủ đề này, có vẻ như việc chuyển SET ANSI_WARNINGS ON, ngầm đặt ARITHABORT thành ON. TUY NHIÊN, nếu SET ARITHABORT OFF cũng được thông qua trong kết nối, ngay cả khi ANSI_WARNINGS ghi đè lên nó, máy chủ SQL vẫn sẽ "hành động" như ARITHABORT bị TẮT, như khi chọn các kế hoạch lạ. Tôi thấy điều này ... không thể tin được. Vì vậy, không còn nghi ngờ gì nữa, điều này cần phải được đặt trong kết nối VÀ TẬP HỢP ARITHABORT thậm chí không thể tồn tại. Trường hợp nhắm lại trong mắt tôi ... sqlservercentral.com/forums/topic/ từ
Eric Swiggum

@EricSwiggum Chủ đề thú vị mà bạn tìm thấy. Tuy nhiên, tôi không thấy cách bạn kết luận từ thông tin đó rằng nó cần được đặt trong kết nối. Nếu không có gì hiện đang ghi đè lên nó, thì chúng tôi biết rằng SET ARITHABORT OFFkhông có mặt. Vậy tại sao phải lo lắng về việc nó có mặt? trường hợp duy nhất chúng ta đã thấy nơi mặc định bị ghi đè là SSMS cài đặt nó ON(đó là một điều tốt). Dù bằng cách nào, tôi đã cập nhật câu trả lời của mình bằng thử nghiệm và những gì tôi thấy là khuyến nghị hợp lý nhất (theo thông tin hiện có).
Solomon Rutzky

1
Tôi đồng ý, kích hoạt cài đặt toàn phiên bản làm mặc định. Nhưng cuối cùng kết nối kiểm soát những gì được thiết lập. Còn trường hợp của các trường hợp được chia sẻ trong đó các công nghệ / giao thức khác nhau đang kết nối với SQL thì sao? Ý tôi là, tôi có phải chạy xung quanh và hét lên "THIẾT LẬP TUYỆT VỜI" để phát triển như một kẻ điên không? hoặc ít nhất, hãy thúc đẩy sự vắng mặt của ARITHABORT OFF nếu có thể .. Tôi cũng thấy kỳ lạ là tôi chưa từng thấy điều này xuất hiện cho đến bây giờ, năm thứ 6 của tôi là một DBA toàn thời gian. hoặc có thể đó là một trường hợp mà tôi đã không nhìn vào nó đủ mạnh. Sao lưu cho tôi Paul hoặc Erland, LOL, chuyện gì thế này?
Eric Swiggum

@EricSwiggum 1) Bạn sẽ không cần phải chạy xung quanh la hét bất cứ điều gì nếu bạn thay đổi mặc định cấp độ cá thể. 2) Bạn sẽ chỉ cần thúc đẩy sự vắng mặt ARITHABORT OFF nếu bạn tìm thấy bất kỳ sự cố thực tế nào của nó. Cho đến nay có khả năng không có. 3) Vì điều này ảnh hưởng đến các kế hoạch truy vấn, có thể các bảng không bao giờ có đủ dữ liệu để khiến SQL Server có một số lựa chọn nhất định để xem xét, hiện tại có nhiều lựa chọn hơn và một số xấu. Hoặc có lẽ có các yếu tố thoáng qua khác, chẳng hạn như số liệu thống kê lỗi thời, vv Không hoàn toàn chắc chắn.
Solomon Rutzky

@EricSwiggum Tôi không đồng ý với bạn ở đó. Tôi nghĩ rằng điều này rất giống với những gì tôi đã đề cập khi bắt đầu câu trả lời của mình (tức là đối chiếu mặc định cho các hệ thống tiếng Anh Mỹ): Microsoft sợ các hệ thống cũ bị lỗi khi nâng cấp (nghĩa là đảm bảo khả năng tương thích ngược) thực sự có hại hơn là thực tế tăng cơ sở cài đặt / phạm vi của kịch bản không lý tưởng. Điều này làm cho nó trở thành một sức hút ngày càng tăng để duy trì trong quá khứ và cơ hội ngày càng giảm đi của mọi thứ trở nên tốt hơn. Đây là những trường hợp tốt hơn hết là xé toạc băng hỗ trợ và bây giờ mới hết đau.
Solomon Rutzky
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.