it-swarm.asia

لماذا يؤدي SET ARITHABORT ON إلى تسريع الاستعلام بشكل كبير؟

الاستعلام عبارة عن تحديد واحد يحتوي على الكثير من مستويات التجميع وعمليات التجميع. مع SET ARITHABORT ON يستغرق أقل من ثانية ، وإلا يستغرق عدة دقائق. لقد رأينا هذا السلوك على SQL Server 2000 و 2008.

79
Jonathan Allen

مؤرخة قليلاً ، ولكن لأي شخص ينتهي هنا بمشكلة مماثلة ...

كان لي نفس المشكلة. بالنسبة لي ، تبين أنه استنشاق المعلمات ، والتي لم أفهمها في البداية بما يكفي لأهتم بها. أضفت "تعيين arithabort على" لإصلاح المشكلة ولكن بعد ذلك عادت. ثم قرأت:

http://www.sommarskog.se/query-plan-mysteries.html

مسح كل شيء. نظرًا لأنني كنت أستخدم Linq إلى SQL ولدي خيارات محدودة لإصلاح المشكلة ، فقد انتهى بي الأمر باستخدام دليل خطة الاستعلام (انظر نهاية الارتباط) لفرض خطة الاستعلام التي أريدها.

63
Jason

تتصل تطبيقات .NET بالخيار الذي تم تعطيله افتراضيًا ، ولكن يتم تمكينه افتراضيًا في Management Studio. والنتيجة هي أن الخادم يخزن في الواقع خطتي تنفيذ منفصلتين لمعظم/جميع الإجراءات. يؤثر هذا على كيفية قيام الخادم بإجراء العمليات الحسابية العددية ، وبالتالي يمكنك الحصول على نتائج مختلفة بشكل كبير اعتمادًا على الإجراء. هذه في الحقيقة واحدة فقط من طريقتين شائعتين يمكن من خلالها الحصول على خطة تنفيذ رهيبة ، والأخرى هي استنشاق المعلمة.

ألق نظرة على https://web.archive.org/web/20150315031719/http://sqladvice.com/blogs/gstark/archive/2008/02/12/Arithabort-Option-Effects-Stored- Actions-Performance.aspx لمزيد من المناقشة حوله.

30
Ben Hoffman

أود أن أزعم أن هذا كان شبه مؤكد شم المعلمة.

كثيرا ما يذكر أن SET OPTIONS يمكن أن يؤثر على الأداء بهذه الطريقة ولكن لم أرَ بعد مصدرًا موثوقًا واحدًا لهذه المطالبة باستثناء الحالة التي تستخدم فيها المشاهدات المفهرسة/الأعمدة المحسوبة المستمرة.

في هذه الحالة (لـ SQL2005 + و ما لم تكن قاعدة البيانات في وضع التوافق مع SQL20 ). إذا كان لديك كل من ARITHABORT و ANSI_WARNINGSOFF ثم ستجد أن الفهرس غير مستخدم ، لذا قد يكون لديك فحص بدلاً من البحث المطلوب (وبعض النفقات العامة حيث لا يمكن استخدام نتيجة الحساب المستمرة). يبدو أن ADO.NET يفترض وجود ANSI_WARNINGS ON من اختبار سريع قمت به للتو.

الادعاء في إجابة بن أن "الطريقة التي يجري بها الخادم العمليات الحسابية العددية" يمكن أن تضيف دقائق إلى نتيجة قد تستغرق أقل من ثانية فقط لا تبدو موثوقة بالنسبة لي. أعتقد أن ما يميل إلى الحدوث هو أنه عند التحقيق في مشكلة في أداء الأداء ، يتم استخدام Profiler لتحديد الاستعلام المسيء. يتم لصق هذا في استوديو الإدارة وتشغيل النتائج وإرجاعها على الفور. الاختلاف الواضح الوحيد بين الاتصالات هو ARITH_ABORT اختيار.

يظهر اختبار سريع في نافذة إدارة الاستوديو أنه عندما SET ARITHABORT OFF قيد التشغيل ويتم تشغيل الاستعلام بحيث تتكرر مشكلة الأداء بحيث يتم إغلاق الحالة على ما يبدو. في الواقع ، يبدو أن هذا هو منهجية استكشاف الأخطاء وإصلاحها المستخدمة في الارتباط Gregg Stark .

ومع ذلك يتجاهل حقيقة أنه مع تعيين هذا الخيار ، قد ينتهي بك الأمر إلى الحصول على نفس الخطة السيئة بالضبط من ذاكرة التخزين المؤقت .

يمكن أن تحدث إعادة استخدام هذه الخطة حتى إذا قمت بتسجيل الدخول كمستخدم مختلف عن المستخدم الذي يستخدمه اتصال التطبيق.

اختبرت هذا عن طريق تنفيذ استعلام اختباري أولاً من تطبيق ويب ثم من استوديو الإدارة مع SET ARITHABORT OFF ويمكن أن نرى زيادة في عدد الحسابات من الاستعلام أدناه.

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) 

لكي تتم مشاركة خطط pf هذه بالفعل ، يجب أن تكون جميع مفاتيح ذاكرة التخزين المؤقت للخطة هي نفسها. بالإضافة إلى arithabort نفسها ، فإن بعض الأمثلة الأخرى هي أن المستخدمين المنفذين يحتاجون إلى نفس المخطط الافتراضي (إذا كان الاستعلام يعتمد على تحليل الاسم الضمني) وتحتاج الاتصالات إلى نفس مجموعة language.

قائمة أكمل من مفاتيح ذاكرة التخزين المؤقت للخطة هنا

21
Martin Smith

أعلم أنني تأخرت عن هذا الحفل ، لكن بالنسبة للزوار المستقبليين ، مارتن صحيح تمامًا. واجهنا هذه المشكلة نفسها - كانSP يعمل ببطء شديد لعملاء .NET ، بينما كان سريعًا جدًا في SSMS. في استكشاف المشكلة وحلها ، أجرينا الاختبار المنهجي الذي يسأل عنه كيني إيفيت في تعليقه على سؤال مارتن.

باستخدام متغير من استعلام مارتن ، بحثت عن SP في ذاكرة التخزين المؤقت للإجراء ووجدت اثنين منهم. بالنظر إلى الخطط ، كان في الواقع أنه تم تشغيل ARITHABORT ON والآخر تم إيقاف تشغيل ARITHABORT. يحتوي إصدار ARITHABORT OFF على بحث عن الفهرس بينما يستخدم إصدار ARITHABORT ON فحصًا للفهرس لنفس الناتج. بالنظر إلى المعلمات المعنية ، كان البحث عن الفهرس يتطلب بحثًا عن عشرات الملايين من السجلات للناتج.

لقد قمت بمسح الإجراءين من ذاكرة التخزين المؤقت وجعلت عميل .NET يشغل SP مرة أخرى ، باستخدام نفس المعلمات (التي تضمنت نطاقًا زمنيًا واسعًا لعميل به الكثير من النشاط). عاد SP على الفور. استخدمت الخطة المخزنة مؤقتًا نفس فحص الفهرس الذي تم عرضه سابقًا في خطة ARITHABORT ON - ولكن هذه المرة كانت الخطة لـ ARITHABORT OFF. قمنا بتشغيل SP بنفس المعلمات في SSMS ، وحصلنا على النتائج مرة أخرى على الفور. الآن رأينا أن الخطة الثانية تم تخزينها مؤقتًا ، لـ ARITHABORT ON ، مع مسح الفهرس.

ثم قمنا بمسح ذاكرة التخزين المؤقت ، وقمنا بتشغيل SP في SSMS بنطاق زمني ضيق وحصلنا على نتيجة فورية. وجدنا أن الخطة المخزنة مؤقتًا الناتجة كانت تحتوي على بحث عن الفهرس ، حيث تم التعامل مع نفس الناتج سابقًا بمسح (والذي كان أيضًا بحثًا في الخطة الأصلية مع ARITHABORT OFF). مرة أخرى من SSMS ، قمنا بتشغيل SP ، هذه المرة بنفس النطاق الزمني الواسع ، وشاهدنا نفس الأداء الرهيب الذي كان لدينا في طلب .NET الأصلي.

باختصار ، لم يكن للتفاوت علاقة بالقيمة الفعلية لـ ARITHABORT - مع تشغيلها أو إيقافها ، من أي عميل ، يمكننا الحصول على أداء مقبول أو رهيب: كل ما يهم هو قيم المعلمات المستخدمة في تجميع الخطة وتخزينها مؤقتًا.

بينما MSDN تشير إلى أن ARITHABORT OFF نفسه يمكن أن يكون له تأثير سلبي على تحسين الاستعلام ، يؤكد اختبارنا أن مارتن صحيح - السبب هو استنشاق المعلمة والنتيجة لا تكون الخطة مثالية لجميع نطاقات المعلمات.

13
mdoyle

فقط واجهت هذه المشكلة. كما قال الناس هنا ، فإن السبب الجذري هو خطط استعلام متعددة ، أحدها دون المستوى الأمثل. أردت فقط التحقق من أن ARITHABORT يمكن أن يتسبب بالفعل في حدوث المشكلة من تلقاء نفسه (حيث إن الاستعلام الذي كنت أواجه مشكلات به لم يكن لديه معلمات ، وهو ما يؤدي إلى إخراج المعلمة من المعادلة).

1
Alan D. Nelson

هذا يذكرني بالمشكلة نفسها التي واجهتها في خادم SQL أيام 2008. في حالتنا ، وجدنا فجأة أن وظيفة sql تباطأت فجأة (عادة بضع ثوان ، والآن 9+ دقائق) ، والمهمة تحتاج إلى الوصول إلى خادم مرتبط ، وقمنا بإضافة ARITHABORT في خطوة المهمة ، وبدا أن المشكلة تم حلها لبضعة أيام ثم عادت.

قمنا لاحقًا بفتح تذكرة مع دعم MS ، وفي البداية لم يتمكنوا من معرفة ذلك أيضًا ، وتم تصعيد التذكرة إلى فريق PFE كبير جدًا ، وحاول اثنان من PFE الدعم اكتشاف هذه المشكلة.

السبب الأخير هو أن بيانات اعتماد المستخدم (لتشغيل خطوة المهمة) لا يمكنها الوصول إلى إحصائيات الجداول الأساسية (على جانب الخادم المرتبط) ، وبالتالي لم يتم تحسين خطة التنفيذ.

بالتفصيل ، ليس لدى المستخدم إذن على SHOW_STATISTICS DBCC (على الرغم من أن المستخدم يمكنه التحديد من الجدول). وفقًا لـ MSDN ، تم تغيير قاعدة الأذونات هذه بعد SP1 2012 sql

أذونات SQL Server وقاعدة بيانات SQL

لعرض كائن الإحصائيات ، يجب أن يمتلك المستخدم الجدول أو يجب أن يكون المستخدم عضوًا في دور خادم sysadmin الثابت أو دور قاعدة البيانات الثابتة db_owner أو دور قاعدة البيانات الثابتة db_ddladmin.

يقوم SQL Server 2012 SP1 بتعديل قيود الأذونات ويسمح للمستخدمين الذين لديهم إذن SELECT باستخدام هذا الأمر. لاحظ أن المتطلبات التالية موجودة لأذونات SELECT لتكون كافية لتشغيل الأمر:

للتحقق من هذه المشكلة ، نحتاج فقط إلى تشغيل المحلل على المثيل الجانبي للخادم المرتبط وتشغيل بعض الأحداث في قسم "الأخطاء والتحذيرات" كما هو موضح أدناه.

enter image description here

نأمل أن تساعد هذه التجربة المجتمع بطريقة أو بأخرى.

1
jyao