انتهت مهلة الاستعلام من تطبيق الويب ولكنها تعمل بشكل جيد من استوديو الإدارة

StackOverflow https://stackoverflow.com/questions/9974

  •  08-06-2019
  •  | 
  •  

سؤال

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

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

كانت حالتي الخاصة تستخدم ASP.NET 2.0 وSql Server 2005، ولكن أعتقد أن المشكلة يمكن أن تنطبق على أي نظام RDBMS.

هل كانت مفيدة؟

المحلول

هذا ما تعلمته حتى الآن من بحثي.

يرسل .NET إعدادات اتصال تختلف عن ما تحصل عليه عند تسجيل الدخول إلى استوديو الإدارة.إليك ما تراه إذا قمت باستنشاق الاتصال باستخدام Sql Profiler:

-- network protocol: TCP/IP  
set quoted_identifier off  
set arithabort off  
set numeric_roundabort off  
set ansi_warnings on  
set ansi_padding on  
set ansi_nulls off  
set concat_null_yields_null on  
set cursor_close_on_commit off  
set implicit_transactions off  
set language us_english  
set dateformat mdy  
set datefirst 7  
set transaction isolation level read committed  

أقوم الآن بلصق هذه الإعدادات فوق كل استعلام أقوم بتشغيله عند تسجيل الدخول إلى خادم SQL، للتأكد من أن الإعدادات هي نفسها.

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

يرتبط التفسير الأكثر احتمالاً باستنشاق المعلمات، وهي تقنية يستخدمها Sql Server لاختيار ما يعتقد أنها خطة الاستعلام الأكثر فعالية.عندما تقوم بتغيير أحد إعدادات الاتصال، قد يختار مُحسِّن الاستعلام خطة مختلفة، وفي هذه الحالة، يبدو أنه اختار خطة سيئة.

لكنني لست مقتنعا تماما بهذا.لقد حاولت مقارنة خطط الاستعلام الفعلية بعد تغيير هذا الإعداد ولم أر بعد الفرق يظهر أي تغييرات.

هل هناك شيء آخر يتعلق بإعداد arithabort قد يتسبب في تشغيل الاستعلام ببطء في بعض الحالات؟

بدا الحل بسيطا:ما عليك سوى وضع set arithabort في الجزء العلوي من الإجراء المخزن.لكن هذا قد يؤدي إلى مشكلة معاكسة:قم بتغيير معلمات الاستعلام وفجأة يعمل بشكل أسرع مع "إيقاف" بدلاً من "تشغيل".

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

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

نصائح أخرى

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

يمكنك أيضًا تأكيد ذلك عن طريق تحديد ملف sproc.عند تنفيذه من SQL Managment Studio، كيف يمكن مقارنة الإدخال/الإخراج عندما تقوم بتشكيله من تطبيق ASP.NET.إذا كانوا كثيرًا، فهذا يؤكد من جديد أنهم يسحبون خطة تنفيذ سيئة.

هل قمت بتشغيل تتبع ASP.NET حتى الآن؟لقد كان لدي مثال حيث لم يكن إجراء SQL المخزن نفسه هو المشكلة، بل كانت حقيقة أن الإجراء أعاد 5000 صف وكان التطبيق يحاول إنشاء عناصر قائمة مرتبطة بالبيانات مع تلك العناصر الـ 5000 التي كانت تسبب المشكلة.

يمكنك الاطلاع على أوقات التنفيذ بين وظائف تطبيق الويب أيضًا من خلال التتبع للمساعدة في تتبع الأمور.

اختبر ذلك على مربع التدريج أولاً، وقم بتغييره على مستوى الخادم لخادم SQL

أعلن @option int

setOption = خيارات | 64

exec sp_configure 'خيارات المستخدم' ، @option

إعادة التكوين

نفس المشكلة التي واجهتها مع خدمات تقارير SQL.حاول التحقق من نوع المتغيرات ، كنت أرسل نوعًا مختلفًا من المتغير إلى SQL مثل إرسال Varchar في مكانه حيث يجب أن يكون عدد صحيح ، أو شيء من هذا القبيل.بعد أن قمت بمزامنة أنواع المتغيرات في خدمة التقارير وفي الإجراء المخزن في SQL، قمت بحل المشكلة.

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

واجهنا نفس المشكلة وهذا ما اكتشفناه.

تم الاحتفاظ بحجم سجل قاعدة البيانات لدينا على الوضع الافتراضي (814 ميجابايت) وكان النمو التلقائي 10٪.على الخادم، تم الاحتفاظ بالحد الأقصى لذاكرة الخادم عند الإعداد الافتراضي أيضًا (2147483647 ميجابايت).

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

حاول تغيير قيمة مهلة SelectCommand:

DataAdapter.SelectCommand.CommandTimeout = 120;
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top