Чому Встановити ARITHABORT ON суттєво прискорить запит?


74

Запит - це єдиний вибір, що містить безліч рівнів групування та операцій агрегації. Якщо SET ARITHABORT ON займає менше секунди, інакше це займе кілька хвилин. Ми спостерігали таку поведінку на SQL Server 2000 та 2008.

Відповіді:


62

Трохи датовано, але для тих, хто закінчується тут із подібною проблемою ...

У мене була така ж проблема. Для мене це виявилося нюханням параметрів, про який я спочатку не розумів достатньо, щоб перейматися. Я додав "встановити arithabort на", який вирішив проблему, але потім він повернувся. Потім я прочитав:

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

Він очистився - усе. Оскільки я використовував Linq для SQL і мав обмежені варіанти, щоб виправити проблему, я в кінцевому рахунку використовував посібник із плану запитів (див. Кінець посилання), щоб примусити план запитів, який я хотів.


3
Більше ніж шість років посилання, дане у цій відповіді, все ще "вимагає читання" ... і все ще актуальне, остання редакція - грудень '17.
takrl

30

Програми .NET підключаються до вимкненої опції за замовчуванням, але вона включена за замовчуванням у програмі Management Studio. Результат полягає в тому, що сервер насправді кешує 2 окремі плани виконання для більшості / всіх процедур. Це впливає на те, як сервер виконує чисельні обчислення, і, як такий, ви можете отримати різко різні результати залежно від процедури. Це дійсно лише один із 2 поширених способів, коли Proc може подати жахливий план виконання, інший - це обнюхування параметрів.

Погляньте на https://web.archive.org/web/20150315031719/http://sqladvice.com/blogs/gstark/archive/2008/02/12/Arithabort-Option-Effects-Stored-Procedure-Performance. aspx для трохи більшого обговорення.


Я згоден із половиною цієї відповіді. Я дуже скептично ставлюся до чисельного твердження про розрахунок!
Мартін Сміт

2
@Martin: Я думаю, я був незрозумілий. Я просто говорив, що ARITHABORT ON змушує SQL Server помилитися з будь-якою дією / 0 або арифметичною помилкою переповнення. Коли він не працює, він продовжується і з будь-якої причини може викликати всілякі жахливі проблеми.

@Ben - Так вибачте, що я не хотів особливо нападати на вашу відповідь, я просто вказував, що було б дуже просто змінити SETваріант отримати кращий план і неправильно діагностувати це як варіант, який винен. Я не переконаний, хлопець у вашому посиланні цього не зробив.
Мартін Сміт

@Martin - Не проблема, я не думав, що ти на мене нападаєш. Інша дискусія, яку я пов'язав, може бути трохи незрозумілою. Я просто намагався дати підтвердження.

@Martin В ретроспективі я вважаю, що ви праві.

21

Я б заперечував, що це майже напевно нюхало параметри.

Часто зазначається, що SET OPTIONSможе вплинути на ефективність таким чином, але я ще не бачив єдиного авторитетного джерела для цієї претензії, за винятком випадків, коли ви використовуєте індексовані обчислювані стовпці / постійні обчислювані стовпці.

У цьому випадку (для SQL2005 + та, якщо ваша база даних не знаходиться в режимі сумісності SQL2000 ). Якщо у вас є обидва, ARITHABORTі ANSI_WARNINGS OFFтоді ви знайдете, що індекс не використовується, тому може мати сканування, а не бажаний пошук (а деякі накладні витрати, оскільки збережений результат обчислення неможливо використовувати). ADO.NET, здається, за замовчуванням отримав ANSI_WARNINGS ONпісля швидкого тестування, який я щойно зробив.

Твердження у відповіді Бена про те, що "те, як сервер виконує числові обчислення", може додати хвилини до результату, який в іншому випадку зайняв би менше секунди, просто не здається мені достовірним. Я думаю, що, як правило, трапляється те, що при дослідженні проблеми продуктивності роботи Profiler використовується для виявлення порушника. Це вставляється в студію управління і запускає і миттєво повертає результати. Єдина очевидна різниця між з'єднаннями - це ARITH_ABORTваріант.

Швидкий тест у вікні студії управління показує, що при SET ARITHABORT OFFвключенні та запуску запиту проблема продуктивності повторюється так, що, очевидно, випадок закритий. Дійсно, це є методологія усунення несправностей, що використовується у посиланні Грегга Старка .

Однак це ігнорує той факт, що за допомогою цього набору параметрів ви можете в кінцевому підсумку отримати такий самий поганий план з кешу .

Таке повторне використання плану може статися, навіть якщо ви ввійшли в систему як інший користувач, ніж використовує з'єднання програми.

Я перевірив це, виконавши тестовий запит спочатку з веб-додатку, потім від студії управління, 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набір.

Більш повний список клавіш кешу плану тут


12

Я знаю, що я спізнююсь на цю вечірку, але для майбутніх відвідувачів Мартін - це абсолютно правильно. Ми зіткнулися з цим самим випуском - SP-клієнт працював дуже повільно для клієнтів .NET, в той час як він швидко спалахував для SSMS. Досліджуючи та вирішуючи проблему, ми провели систематичне тестування, про яке питає Кенні Евітт у коментарі до питання Мартіна.

Використовуючи варіант запиту Мартіна, я пошукав SP в кеші процедур і знайшов два з них. Дивлячись на плани, насправді так сталося, що в одному було ARITHABORT ON, а в одному ARITHABORT OFF. Версія ARITHABORT OFF мала шукати індекс, тоді як версія ARITHABORT ON використовувала сканування індексу для цього ж виходу. З огляду на параметри, що потребують пошуку, індекс потребує пошуку десяти мільйонів записів для виводу.

Я очистив дві процедури з кешу і змусив клієнта .NET запустити SP знову, використовуючи ті самі параметри (які містили широкий діапазон дат для клієнта з великою активністю). СП повернувся миттєво. У кешованому плані використовувався той самий сканування індексу, який раніше містився в плані ARITHABORT ON, але цього разу план був для ARITHABORT OFF. Ми запустили SP з тими ж параметрами в SSMS і знову отримали результати миттєво. Тепер ми побачили, що другий план був кешований, для ARITHABORT ON, із скануванням індексу.

Потім ми очистили кеш, запустили SP в SSMS з вузьким діапазоном дат і отримали миттєвий результат. Ми виявили, що отриманий кешований план мав пошук індексів, тому що той самий вихід попередньо оброблявся за допомогою сканування (що також було пошуком у вихідному плані з ARITHABORT OFF). Знову з SSMS ми запустили SP, цього разу з однаковим широким діапазоном дат, і побачили таку ж жахливу ефективність, яку ми мали в оригінальному запиті .NET.

Коротше кажучи, невідповідність не мала нічого спільного з фактичним значенням ARITHABORT - з увімкненням або вимкненням будь-якого клієнта ми могли отримати прийнятну або жахливу продуктивність: Все, що було важливим, полягала в значеннях параметрів, використовуваних при складанні та кешуванні плану.

Незважаючи на те, що MSDN вказує, що ARITHABORT OFF сам може негативно впливати на оптимізацію запитів, наше тестування підтверджує, що Мартін є правильним - причиною було обнюхування параметрів, а отриманий план не був оптимальним для всіх діапазонів параметрів.


1
Поцікавтеся, що Setting ARITHABORT to OFF can negatively impact query optimization leading to performance issues.означає ця фраза . Чи говорять вони лише про неможливість використання індексів для обчислених стовпців і представлень (якщо ANSI_WARNINGSвони також вимкнено), чи це дійсно має якийсь інший ефект.
Мартін Сміт

Я не впевнений. Цікаво, чи просто так, що хтось із MSDN зіткнувся з подібною ситуацією, встановив ARTIHABORT на ON, побачив покращення продуктивності та перейшов до тих же висновків, які мають інші. Що стосується індексованих представлень та обчислених стовпців, мені незрозуміло. Одного разу він заявляє, що параметри SET повинні мати конкретні значення, якщо операція INSERT, UPDATE або DELETE змінює збережені в них значення даних. В іншому випадку вони заявляють, що оптимізатор буде ігнорувати індекси для "будь-якого запиту", на який посилається зазначений індексований вигляд або обчислений стовпець. Чи це правда, чи це справді "будь-який запит, що змінює дані"?
mdoyle

1

Просто була ця проблема. Як говорили тут люди, першопричиною є кілька планів запитів, один з яких є неоптимальним. Я просто хотів переконатися, що ARITHABORT дійсно може викликати проблему сам по собі (так як запит, у якого у мене виникли проблеми, не мав жодних параметрів, який приймає нюхання параметра з рівняння).


1

Це нагадує мені саме таку проблему, яку я відчував на сервері sql 2008 року. У нашому випадку ми раптом виявили, що одна робота sql раптово сповільнилася (як правило, кілька секунд, а зараз 9+ хвилин), завдання потрібно отримати доступ до підключеного сервера, ми додали встановити ARITHABORT на кроці роботи, і це здалося проблемою було вирішено кілька днів, а потім повернуто.

Пізніше ми відкрили квиток із підтримкою MS, і спочатку їх так і не вдалося дізнатися, і квиток був переданий дуже старшій команді PFE, і двоє PFE намагалися вирішити цю проблему.

Кінцева причина полягає в тому, що обліковий запис користувача (для виконання етапу завдання) не може отримати доступ до статистики базових таблиць (на стороні пов'язаного сервера), і тому план виконання не оптимізований.

Детально, користувач не має дозволу на DBCC SHOW_STATISTICS (хоча користувач може ВИБІРАТИ з таблиці). Згідно з MSDN , це правило дозволу змінюється після sql 2012 SP1

Дозволи для SQL Server та бази даних SQL

Для перегляду об’єкта статистики користувач повинен володіти таблицею або користувач повинен бути членом ролі фіксованого сервера sysadmin, ролі бази даних db_owner з фіксованою базою даних або ролі бази даних db_ddladmin з фіксованою базою даних.

SQL Server 2012 SP1 змінює обмеження дозволу та дозволяє користувачам з дозволом SELECT використовувати цю команду. Зауважте, що для дозволу SELECT є достатніми вимоги для запуску команди:

Щоб перевірити цю проблему, нам просто потрібно запустити профайлер на приєднаному екземплярі сервера та включити деякі події в розділі "Помилки та попередження", як показано нижче.

введіть тут опис зображення

Сподіваюся, що цей досвід може якось допомогти громаді.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.