Настроювання запитів 101
Немає чарівної срібної кулі для налаштування запитів, хоча я можу дати вам підказки та поради. Перше, що потрібно зробити - зрозуміти, що насправді відбувається за лаштунками. Отримайте хорошу внутрішню книгу, як-от третя книга Посібника Гуру.
Погано виконуючі запити, як правило, мають два основні смаки: запити транзакцій, які займають занадто багато часу, і шліфування пакетних завдань (або звітів), які займають занадто довго. Хороший знак запиту, в якому щось не так - це окремий елемент плану запитів, який займає 99% часу.
Трансакційні запити
У більшості випадків неякісний запит трансакцій є однією з кількох речей:
Відсутній індекс. Це можна побачити в плані запитів - сканування таблиць великих таблиць на з'єднання, яке повинно бути дуже вибіркове (тобто повернути кілька рядків).
Запит не може використовувати індекс. Якщо у пункті "де" є умови АБО, приєднується до обчисленого значення чи іншому елементу запиту, який не може бути sarg-можливо, тоді вам може знадобитися переписати запит. Якщо коротко, sargs - це предикати запитів, які можуть використовувати індекси для усунення рядків. Логічні І, рівність і нерівність (>,> =, <, <= і! =) - все це можливо. АБО традиційно не здатний до саргування. Однак ви часто можете переводити АБО в sarg-здатні предикати, перевертаючи сенс з конструкцій типу "АБО" в "НЕ" (foo і не бар).
Неефективні предикати. Наприклад, якщо у вас є where in
посилання на вкладений підзапит, перевірте, чи може він бути переписаний як where exists
або як об'єднання. Це може призвести до більш ефективних планів запитів, і ось інші стандартні переписування ви також можете спробувати. Знову ж таки, довідники Гуру та інші на цю тему є гарною відправною точкою.
Пакетні запити
Пакетні запити є складнішими та мають різні проблеми налаштування. Деякі поради:
Індексація. Це може істотно змінитись з тієї ж причини, що і з трансакційними запитами. Часто доброю ознакою відсутнього індексу є довга операція шліфування (99% плану запитів), яка, здається, не перемолола машину.
Тимчасові столи. Можливо, вам буде краще розбити запит на кілька запитів, що містять тимчасові таблиці. Більші запити дають оптимізатору більше місця для викрутки, хоча це менше питання, ніж раніше. Зробіть таблиці темп, select into
оскільки ця операція мінімально реєструється (набагато менше активності журналу), що зменшує навантаження вводу / виводу.
Зауважте, що тимчасові таблиці в tempdb - це та сама структура даних, яку оптимізатор використовує для зберігання проміжних результатів з'єднання, тому за це не передбачено покарання за ефективність. Ви також можете створити індекс (включаючи кластеризовані та охоплюючі індекси) на темп-таблиці, що може покращити ефективність запитів, читаючи його з тих же причин, що вони покращують запити в статичних таблицях.
Однак не перестарайтеся з тимчасовими таблицями, оскільки вони можуть ускладнити відстеження за запитом. Для менших таблиць у межах збереженої процедури перевіряйте, чи допомагають змінні таблиці. Це структура даних в пам'яті, тому вони можуть стати виграшним показником.
Кластеризовані та охоплюють індекси. Вони можуть покращити ефективність запиту, оскільки вони змушують локальність посилання на диску на основі деякого стовпчика групування. Кластерний індекс може істотно змінити ефективність пакетної роботи.
Неефективні предикати. Вони можуть спричинити проблеми із заригами та іншими субсептимізаційними аналізами приблизно так само, як і з транзакційними запитами.
Сканування таблиці - ваш друг. Всупереч поширеній думці, сканування таблиці не є по суті злом. Як правило, вони є ознакою чогось неправильного в запиті трансакцій, але вони часто є найбільш ефективним способом зробити велику пакетну операцію. Якщо ви робите щось із кількома відсотками рядків у таблиці, сканування таблиці найчастіше є найбільш ефективним способом накрити таблицю.
Приєднуються вкладені петлі. Погляньте, що робить оптимізатор з обох сторін з'єднання. Вони можуть бути неефективними, якщо ви є (наприклад, сканування таблиці двох великих таблиць з обох сторін вкладених циклів об'єднання. Подумайте про використання кластерних індексів або order by
намагання змінити операцію на об'єднання злиття або натякнути на просування хеш-з'єднання, якщо одна сторона є досить малий, щоб це зробити.
Блокування
Блокування також може спричинити проблеми з продуктивністю. Якщо ваша система погано спрацьовує під навантаженням, перегляньте лічильники профілів та парфмонів, пов'язані із замками, і перевірте, чи є суттєві суперечки. sp_who2
У наборі результатів стовпчик "BlkBy", який показує, чи запит заблокований та що його блокує. Крім того, для усунення проблем із блокуванням можуть бути корисні профілі із подіями 'графік тупикової ситуації' (якщо у вас є запит із блокуванням запитів) та пов’язані із цим запитом події.