Това е, което научих досега от моето изследване.
.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 секунди на 1 секунда.
Най-вероятното обяснение е свързано с подслушването на параметри, което е техника, която Sql Server използва, за да избере това, което смята за най-ефективния план за заявка. Когато промените една от настройките на връзката, оптимизаторът на заявки може да избере различен план и в този случай очевидно е избрал лош.
Но не съм напълно убеден в това. Опитах да сравня действителните планове за заявка след промяна на тази настройка и все още не съм виждал разликата да показва промени.
Има ли нещо друго в настройката arithabort, което може да доведе до бавно изпълнение на заявката в някои случаи?
Решението изглеждаше просто:просто поставете set arithabort в горната част на съхранената процедура. Но това може да доведе до обратния проблем:променете параметрите на заявката и изведнъж тя работи по-бързо с 'off', отколкото 'on'.
За момента изпълнявам процедурата 'с прекомпилиране', за да се уверя, че планът се регенерира всеки път. Добре е за този конкретен отчет, тъй като отнема може би секунда за прекомпилиране и това не е много забележимо при отчет, който отнема 1-10 секунди, за да се върне (това е чудовище).
Но това не е опция за други заявки, които се изпълняват много по-често и трябва да се връщат възможно най-бързо, само за няколко милисекунди.