Оптимізація: переміщення оголошень змінних у верхній частині вашої процедури


15

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

Одне згадане DBA було те, що я повинен оголосити всі змінні (особливо TABLEті) у верхній частині збереженої процедури, щоб уникнути перекомпіляцій.

Це перший, який я чув про це, і шукав певного підтвердження, перш ніж переглянути всі різні збережені нами процедури. Він називав це "пізнім переглядом коду", а перекомпіляція блокувала схему, яка б враховувала блокування.

Чи зменшення всіх оголошень змінної до верхньої частини вашої збереженої процедури зменшує перекомпіляції?

Відповіді:


18

Ні.

Це раніше було правдою (і вже не, принаймні з часу SQL Server 2000), або ніколи не було правдою, і ваш DBA просто переплутав свою рекомендацію з наступною :

Важливо згрупувати всі оператори DDL (наприклад, створення індексів) для тимчасових таблиць на початку збереженої процедури. Розміщуючи ці оператори DDL разом, непотрібні компіляції через зміну схеми можна уникнути.

Ви можете знайти ще одне пояснення мотивів цієї рекомендації на цій сторінці .

Якщо ми подивимось на цей Microsoft KB , ми побачимо, що причиною перекомпіляції збереженої процедури може бути одна з наступних (SQL Server 2005+):

  1. Схема змінена.
  2. Статистика змінилася.
  3. Перекомпілюйте DNR.
  4. Параметр встановлення змінено.
  5. Таблиця темпів змінена.
  6. Віддалений набір рядків змінено.
  7. Для перегляду perms змінено.
  8. Середовище сповіщень про запити змінено.
  9. Перегляд MPI змінено.
  10. Параметри курсору змінено.
  11. З опцією перекомпіляції.

Оголошення змінної - навіть табличної змінної (тобто @table_variable) - не може викликати жодну з цих подій, очевидно, тому що оголошення змінної не вважається DDL . Змінна (навіть таблична змінна) - тимчасовий об'єкт, який використовується виключно для програмування T-SQL. Ось чому змінні таблиці не отримують статистики і не пов'язані транзакціями . Оголошення змінної (таблиця чи ні) не може викликати перекомпіляцію proc.

#temp_tableОднак створенням тимчасової таблиці (тобто ) або індексу є DDL, який впливає на фізичне визначення бази даних. Тимчасові таблиці та індекси - це "справжні" об'єкти зі статистикою та транзакційним контролем, тому їх створення може запустити будь-яку з подій 1, 2 або 5 у списку вище і таким чином викликати процедуру перекомпіляції.


3

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

Щоб потрапити на частину питання "про що думає моя DBA", єдине, що я можу придумати (окрім точки зору Ніка, що вони думають про те, як щось було раніше), - це, можливо, вони говорили про параметр "Sniffing" (Див. Варіант 2 за цим посиланням на простій бесіді)

Про ваше блокування -> Якщо ви бачите справжнє блокування, це не той тип суперечок блокування компіляції, про який йдеться у вашому DBA. Хоча це правда, що на це впливають певні речі (наприклад, не класифікаційні таблиці схеми, не схема, яка кваліфікує ваші збережені виклики процедури), це не є причиною ваших високих читань, безумовно, і, швидше за все, не є причиною вашого блокування. Ви обов'язково повинні зробити все можливе, щоб уникнути цих блокування компіляції. Але я б розглядав настройку та оптимізацію решти збереженого коду процедури як важливіше завдання, ніж турбуватися про те, де знаходяться змінні. Ви також можете прочитати Як визначити та вирішити блокування компіляції, якщо ви хочете перевірити, що тут не виникають проблеми.

Опублікуйте ці до / після прикладів, і ми побачимо, що DBA веде тут.

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