Монументальна різниця у часі виконання запитів при використанні підказки RECOMPILE


16

У мене є два майже однакових запиту, що працюють на одному екземплярі SQL Server 2005:

  1. Перший - це оригінальний SELECTзапит, згенерований LINQ (я знаю, я знаю ... Я не розробник додатків, просто DBA :).
  2. Другий точно такий же, як і перший, доданий в OPTION (RECOMPILE)кінці.

Нічого іншого не змінилося.

Перший займає 55 секунд кожного разу, коли він працює.
Другий займає 2 секунди.

Обидва набори результатів однакові.

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

Запис "Книги в Інтернеті RECOMPILE" не пропонує дуже детального пояснення:

Доручає двигуну баз даних SQL Server відкидати план, сформований для запиту після його виконання, змушуючи оптимізатор запитів перекомпілювати план запитів наступного разу, коли буде виконаний той самий запит. Не вказуючи RECOMPILE, Database Engine кешує плани запитів і повторно використовує їх. Під час компіляції планів запитів підказка запиту RECOMPILE використовує поточні значення будь-яких локальних змінних у запиті, і, якщо запит знаходиться в межах збереженої процедури, поточні значення передаються будь-яким параметрам.

RECOMPILE є корисною альтернативою для створення збереженої процедури, яка використовує пункт З RECOMPILE, коли потрібно рекомпілювати лише підмножину запитів всередині збереженої процедури, а не всю збережену процедуру. Для отримання додаткової інформації див. Перекомпонування збережених процедур. RECOMPILE також корисний при створенні напрямних планів. Для отримання додаткової інформації див. Оптимізація запитів у розгорнутих програмах за допомогою посібників із плану.

Оскільки мій запит має багато локальних змінних, я гадаю, що SQL Server може (серйозно) оптимізувати його, коли я використовую OPTION (RECOMPILE)підказку запиту.

Скрізь, де я дивлюся, люди кажуть, що цього OPTION (RECOMPILE)слід уникати. Пояснення цього загалом полягає в тому, що використання цього підказки SQL Server не в змозі повторно використовувати цей план виконання, і тому доводиться витрачати час на його перекомпіляцію щоразу.
(Але) Враховуючи гігантську перевагу продуктивності, я схильний думати, що використання цього підказки цього разу було б хорошою справою.

Чи варто його використовувати? Якщо ні, чи можна змусити SQL Server використовувати кращий план виконання без цього підказки та без зміни програми?

Відповіді:


16

Як зафіксовано у статті Статистика, що використовується оптимізатором запитів у Microsoft SQL Server 2005

Якщо ви використовуєте локальну змінну в предикаті запиту замість параметра або літералу, оптимізатор вдається до оцінки зниженої якості або догадки про вибірковість предиката. Використовуйте параметри або літерали у запиті замість локальних змінних

Коли оптимізатор не має корисної статистики для стовпця, він здогадається, що =предикат відповідатиме 10% рядків, BETWEEN9%, а будь-який з >, >=, < and <=30%. Якщо є доступна статистика стовпців, =предикат буде розглядатися інакше, як показано нижче.

Навіть коли в запиті використовуються локальні змінні, у випадку предикатів рівності використовується оцінка, яка краща за здогаду. Вибірковість для умов форми " @local_variable = column_name" оцінюється за допомогою середньої частоти значень з гістограми для імені стовпця. Так, наприклад, якщо стовпець колонки_ім'я містить усі унікальні значення, то 1/(number of unique values in column)буде використана оцінка селективності , яка є точною.

Отже, це по суті те саме, що використовувати для OPTIMIZE FOR (UNKNOWN). Це може бути більш точним, ніж однозначна 10%здогадка, але він не адаптований до конкретних значень, які ви запитуєте.

Щоб змусити SQL Server оптимізувати запит кожного разу, коли він запускається, і використовувати значення локальних змінних для оцінки кардинальності та вартості під час оптимізації запиту, додайте RECOMPILEпідказку до запиту.

RECOMPILEІмовірно, із застосуванням ви отримуєте більш точні оцінки кардинальності, і тому інший план із типовими замовленнями / типами приєднання більше відповідає кількості рядків, повернутих з різних частин вашого фактичного запиту.

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