สิ่งที่เป็นประโยชน์ของการตั้งค่า ARITHABORT ON สำหรับการเชื่อมต่อทั้งหมดใน SQL Server?


10

ดังนั้นผมจึงได้พิจารณาแล้วว่าพฤติกรรมผิดปกติของ SQL Server ของฉันคือเนื่องจากการตั้งค่าเริ่มต้นของผู้ให้บริการสุทธิ SqlClient SET ARITHABORT OFFข้อมูลของ ด้วยที่กล่าวว่าฉันได้อ่านบทความต่าง ๆ ที่ถกเถียงวิธีที่ดีที่สุดในการใช้งาน สำหรับฉันฉันแค่ต้องการวิธีที่ง่ายเพราะ SQL Server กำลังทนทุกข์และการปรับแต่งการสืบค้นของฉันยังไม่ได้มีการข้ามผ่านแอพอย่างสมบูรณ์ (และแน่นอนว่าการเพิ่มSETใน sp ไม่ทำงาน)

ในบทความยอดเยี่ยมเกี่ยวกับหัวข้อของ Erland Sommarskog เขาแนะนำให้ใช้วิธีการที่ปลอดภัยโดยการเปลี่ยนแอพให้เป็นปัญหาSET ARITHABORT ONสำหรับการเชื่อมต่อ อย่างไรก็ตามในคำตอบนี้จากคำถาม dba.stackexchange โซโลมอน Rutzky เสนอวิธีการแบบกว้างและแบบฐานข้อมูล

ฉันหายไปที่นี่โดยการตั้งค่าทั้งอินสแตนซ์นี้ได้อย่างไร ตามที่ฉันเห็น ... เนื่องจาก SSMS มีการตั้งค่านี้ONตามค่าเริ่มต้นฉันไม่เห็นอันตรายใด ๆ ในการตั้งค่าทั้งONเซิร์ฟเวอร์สำหรับการเชื่อมต่อทั้งหมด ในตอนท้ายของวันฉันแค่ต้องการ SQL Server นี้เพื่อดำเนินการเหนือสิ่งอื่นใด


การอ่านคำตอบของฉันที่คุณเชื่อมโยงไปถึงคำถามตอนนี้ดูเหมือนว่าจะปิดโดยปริยายลูกค้าบางรายเปิดใช้งานโดยเฉพาะ แต่ EF / SqlClient ไม่แตะต้องซึ่งหมายความว่ามันยังคงเป็น OFF
โซโลมอน Rutzky

1
ไม่ใช่ EF แต่คุณยกประเด็นที่น่าสนใจด้วยวิธีที่ EF สามารถแก้ไขการตั้งค่าแบบกว้างได้ ดังนั้นหากการเชื่อมต่อสามารถแทนที่นี้เห็นได้ชัดว่าเป็นสถานที่ที่น่าเชื่อถือมากที่สุดที่จะมีชุดนี้มาจากภายในการเชื่อมต่อที่จะจัดตั้งขึ้นเพื่อ SQL Server, ถ้าเป็นไปได้ ...
เอริค Swiggum

1
"ตั้งค่า ARITHABORT เป็น ON เสมอในเซสชันการเข้าสู่ระบบของคุณการตั้งค่า ARITHABORT เป็นปิดอาจส่งผลกระทบในทางลบต่อการปรับให้เหมาะสมของแบบสอบถามซึ่งนำไปสู่ปัญหาด้านประสิทธิภาพ" บทความนี้จาก microsoft พูดว่า: docs.microsoft.com/en-us/sql/t-sql/statements/ …
Shiwangini Shishulkar

ฉันได้ทดสอบสถานการณ์ต่างๆแล้วสิ่งสุดท้ายที่ฉันทำได้จากทั้งหมดคือการตั้งค่าและการดมกลิ่นพารามิเตอร์เป็นเตียงนอน ถ้าคุณมีARITHABORT OFFก็ไม่เป็นไร ปิดไว้สำหรับการเชื่อมต่อที่เข้ามาทั้งหมด (ขอให้โชคดีในการควบคุม) แต่เมื่อการเชื่อมต่อมีการตั้งค่าเป็นเปิดดังนั้น SQL จะสร้างแผนคิวรีใหม่ซึ่งอาจส่งผลกระทบต่อประสิทธิภาพการทำงาน เอาของฉันตั้งเป็น ON เป็นตัวเลือกผู้ใช้เริ่มต้นที่ระดับอินสแตนซ์และปรับแต่งแบบสอบถามตาม
Eric Swiggum

คำตอบ:


11

มีค่าเริ่มต้นบางอย่างที่มีอยู่เพียงเพราะไม่มีใครรู้ว่าผลของการเปลี่ยนพวกเขาจะเป็นอย่างไร ยกตัวอย่างเช่นการเริ่มต้นการเปรียบเทียบเช่นระดับเมื่อติดตั้งในระบบที่ใช้ "ภาษาอังกฤษ" เป็นภาษา OS SQL_Latin1_General_CP1_CI_ASคือ สิ่งนี้ไม่สมเหตุสมผลเนื่องจากการSQL_*เปรียบเทียบมีไว้สำหรับความเข้ากันได้ของ SQL Server 2000 เริ่มต้นใน SQL Server 2000 คุณจริงสามารถเลือกการเปรียบเทียบของ Windows และอื่น ๆ เริ่มต้นสำหรับระบบภาษาอังกฤษของสหรัฐอเมริกาควรจะLatin1_General_CI_ASมีการเปลี่ยนแปลงไป แต่ฉันเดาว่าไม่มีใครใน Microsoft รู้จริง ๆ ว่าผลกระทบจะเป็นอย่างไรต่อระบบย่อยที่มีศักยภาพและกระบวนการจัดเก็บระบบ ฯลฯ

ดังนั้นฉันไม่ได้ตระหนักถึงผลกระทบเชิงลบใด ๆ ของการตั้งค่าเป็น ON ไม่ว่าจะเป็นค่าเริ่มต้นของฐานข้อมูลหรือแม้แต่อินสแตนซ์ ในขณะเดียวกันฉันยังไม่ได้ทดสอบ แต่แม้ว่าฉันได้ทำการทดสอบแล้วฉันอาจยังไม่ได้ใช้เส้นทางรหัสเดียวกันกับแอปพลิเคชันของคุณดังนั้นนี่คือสิ่งที่คุณจำเป็นต้องทดสอบในสภาพแวดล้อมของคุณ ตั้งเป็นONที่ระดับอินสแตนซ์ในสภาพแวดล้อม Dev และ QA ของคุณและดูว่ามันใช้งานได้หนึ่งหรือสองเดือน จากนั้นเปิดใช้งานใน Staging / UAT หากทุกอย่างยังคงดำเนินต่อไปได้ดีเป็นเวลาหลายสัปดาห์ให้เปลี่ยนการกำหนดค่าเป็นการผลิต กุญแจสำคัญคือการให้เวลามากที่สุดเท่าที่จะทำได้สำหรับการทดสอบพา ธ ของรหัสต่างๆที่ไม่ได้ตีทุกวัน บางคนถูกโจมตีทุกสัปดาห์หรือหลายเดือนหรือทุกปี เส้นทางโค้ดบางอย่างได้รับการสนับสนุนโดยเฉพาะหรือรายงานเฉพาะกิจหรือ proc การบำรุงรักษาที่ใครบางคนสร้างเมื่อหลายปีก่อนและไม่เคยบอกคุณเกี่ยวกับและจะได้รับการใช้งานในช่วงเวลาสุ่มเท่านั้น (nah นั่นไม่เคยเกิดขึ้น

ดังนั้นฉันทำการทดสอบอินสแตนซ์ที่ยังคงมีการตั้งค่า "ตัวเลือกผู้ใช้" เริ่มต้นเนื่องจากฉันไม่เคยเปลี่ยนแปลง

โปรดทราบ:

  • @@OPTIONS/ 'user options'เป็นค่าบิตมาสค์
  • 64 เป็นบิตสำหรับ ARITHABORT ON

ติดตั้ง

ฉันทดสอบกับทั้ง SQLCMD (ซึ่งใช้ ODBC) และ LINQPad (ซึ่งใช้. 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 .

( ^ตัวอักษรคือตัวต่อเนื่องของ DOS บรรทัด.สุดท้ายคือเพียงเพื่อบังคับให้เพิ่มบรรทัดพิเศษเพื่อให้คัดลอกและวางได้ง่ายขึ้น)

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

ทดสอบ 1: ก่อน

SQLCMD ส่งคืน:

master: 0 (ODBC)

LINQPad คืนค่า:

tempdb: 0 (.Net SqlClient Data Provider)

เปลี่ยนตัวเลือกการเชื่อมต่อเริ่มต้น:

T-SQL ต่อไปนี้เปิดใช้งานARITHABORTโดยไม่ลบตัวเลือกอื่น ๆ ที่อาจถูกตั้งค่าและไม่เปลี่ยนแปลงอะไรเลยหากARITHABORTตั้งค่าไว้ในค่าบิตมาร์กแล้ว

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;

ทดสอบ 2: หลังจาก

SQLCMD ส่งคืน:

master: 64 (ODBC)

LINQPad คืนค่า:

tempdb: 64 (.Net SqlClient Data Provider)

ข้อสรุป

ระบุว่า:

  1. ดูเหมือนจะไม่มีประโยชน์ใด ๆ ที่จะมี ARITHABORT OFF
  2. มีประโยชน์ต่อการมี ARITHABORT ON
  3. การตั้งค่าการเชื่อมต่อเริ่มต้น (เว้นแต่จะถูกแทนที่ด้วยการเชื่อมต่อ) = OFF
  4. ไม่ปรากฏว่ามีความพยายามในการตั้งค่า ODBC หรือ OLEDB / .NET SqlClient ARITHABORTดังนั้นจึงยอมรับการตั้งค่าเริ่มต้น

ฉันขอแนะนำให้เปลี่ยนตัวเลือกการเชื่อมต่อเริ่มต้นของอินสแตนซ์กว้าง (ดังที่แสดงด้านบน) นี่จะน้อยกว่าการอัปเดตแอปพลิเคชัน ฉันจะอัปเดตแอปเฉพาะเมื่อคุณพบปัญหาเกี่ยวกับการเปลี่ยนการตั้งค่าอินสแตนซ์กว้าง

PS ฉันทำการทดสอบอย่างง่าย ๆ ด้วยการเปลี่ยนแปลงtempdbและไม่เปลี่ยนการตั้งค่าทั้งอินสแตนซ์และดูเหมือนจะไม่ทำงาน


1
อืมหลังจากอ่านคำถามและคำตอบนี้กับ Paul White ในเรื่องปรากฏว่าผ่านการตั้งค่า ANSI_WARNINGS ON ตั้งค่า ARITHABORT เป็น ON อย่างไรก็ตามถ้า SET ARITHABORT OFF ถูกส่งผ่านไปยังการเชื่อมต่อแม้ว่า ANSI_WARNINGS จะแทนที่เซิร์ฟเวอร์ SQL จะยังคง "ทำหน้าที่" เหมือน ARITHABORT ปิดอยู่ในการเลือกแผนแปลก ๆ ฉันพบสิ่งนี้ ... เหลือเชื่อ ดังนั้นไม่ต้องสงสัยเลยว่าสิ่งนี้จะต้องถูกตั้งค่าในการเชื่อมต่อและ SET ARITHABORT OFF ไม่สามารถมีอยู่ได้ กรณีปิดในตาของฉัน ... sqlservercentral.com/forums/topic/…
Eric Swiggum

@EricSwiggum เธรดที่น่าสนใจที่คุณพบ อย่างไรก็ตามฉันไม่เห็นวิธีที่คุณสรุปจากข้อมูลนั้นว่าจะต้องมีการตั้งค่าในการเชื่อมต่อ ถ้าไม่มีอะไรในปัจจุบันคือการเอาชนะมันแล้วเรารู้ว่าSET ARITHABORT OFFเป็นไม่ได้ในปัจจุบัน เหตุใดจึงต้องกังวลว่ามันมีอยู่? อินสแตนซ์เดียวที่เราเห็นซึ่งค่าเริ่มต้นถูกแทนที่คือ SSMS ตั้งค่าเป็นON(ซึ่งเป็นสิ่งที่ดี) ทั้งสองวิธีฉันได้อัปเดตคำตอบของฉันด้วยการทดสอบและสิ่งที่ฉันเห็นว่าเป็นคำแนะนำที่สมเหตุสมผลที่สุด (ต่อข้อมูลที่มีอยู่)
โซโลมอน Rutzky

1
ฉันยอมรับให้เปิดใช้งานการตั้งค่าทั้งอินสแตนซ์เป็นค่าเริ่มต้น แต่ในที่สุดการเชื่อมต่อจะควบคุมสิ่งที่ตั้งไว้ สิ่งที่เกี่ยวกับกรณีของอินสแตนซ์ที่ใช้ร่วมกันที่เทคโนโลยี / โปรโตคอลต่าง ๆ เชื่อมต่อกับ SQL ฉันหมายถึงฉันต้องวิ่งไปรอบ ๆ และตะโกน "SET ARITHABORT ON" เพื่อการพัฒนาเหมือนคนบ้าเหรอ? หรืออย่างน้อยที่สุดส่งเสริมการขาด ARITHABORT OFF ถ้าเป็นไปได้ .. ฉันยังพบว่ามันแปลกที่ฉันไม่ได้เห็นสิ่งนี้มาถึงหัวจนถึงตอนนี้ปีที่ 6 ของฉันในฐานะ DBA แบบเต็มเวลา หรืออาจเป็นกรณีที่ฉันไม่ได้มองมันหนักพอ กลับมาหาฉัน Paul หรือ Erland, LOL เกิดอะไรขึ้นกับสิ่งนี้?
Eric Swiggum

@EricSwiggum 1) คุณไม่จำเป็นต้องเรียกใช้เสียงตะโกนหากคุณเปลี่ยนค่าเริ่มต้นระดับอินสแตนซ์ 2) คุณจะต้องส่งเสริมการขาดงานARITHABORT OFF หากคุณพบว่ามีเหตุการณ์จริงเกิดขึ้น จนถึงขณะนี้ยังไม่มีใคร 3) เนื่องจากสิ่งนี้มีผลต่อแผนการสืบค้นอาจเป็นไปได้ว่าตารางไม่เคยมีข้อมูลเพียงพอที่จะทำให้ SQL Server มีตัวเลือกบางอย่างที่ต้องพิจารณาซึ่งขณะนี้มีตัวเลือกเพิ่มเติมและบางตัวก็ไม่ดี หรืออาจมีปัจจัยชั่วคราวอื่น ๆ เช่นสถิติล้าสมัยเป็นต้นไม่แน่ใจทั้งหมด
โซโลมอน Rutzky

@EricSwiggum ฉันไม่เห็นด้วยกับคุณที่นั่น ฉันคิดว่านี่คล้ายกับสิ่งที่ฉันพูดถึงเมื่อเริ่มต้นคำตอบของฉัน (เช่นการเปรียบเทียบที่เป็นค่าเริ่มต้นสำหรับระบบภาษาอังกฤษของสหรัฐอเมริกา): ความกลัวของ Microsoft เกี่ยวกับระบบดั้งเดิมที่ได้รับข้อผิดพลาดเมื่ออัปเกรด เพิ่มการติดตั้งฐาน / ขอบเขตของสถานการณ์ที่ไม่เหมาะ สิ่งนี้ทำให้เกิดแรงดึงดูดที่เพิ่มขึ้นเรื่อย ๆ ในอดีตและโอกาสที่สิ่งต่าง ๆ จะดีขึ้นเรื่อย ๆ กรณีเหล่านี้เป็นกรณีที่ดีกว่าที่จะฉีกวงช่วยเหลือออกและเพียงแค่ได้รับความเจ็บปวดด้วยตอนนี้
โซโลมอน Rutzky
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.