Published on

October 7, 2022

Исследование подсказок SQL Server Query с использованием DMV

Как администратор баз данных, важно иметь четкое представление о выполняемых запросах в вашей системе SQL Server. Одно из распространенных требований – определить запросы, которые содержат подсказки, такие как подсказки таблицы, подсказки индекса или подсказки запроса. В этой статье мы рассмотрим метод быстрого инвентаризации всех запросов с подсказками с использованием динамических представлений управления (DMV).

Проблема инвентаризации запросов

Ручной анализ кода в sys.sql_modules – это распространенный подход для поиска запросов с подсказками. Однако этот метод может давать ложные срабатывания и неэффективен для запросов, выполняемых ad hoc или динамически генерируемых в приложениях. Другой подход – использование трассировки на стороне сервера или профилировщика, но это может создавать значительную нагрузку на сервер и полагаться на свободные правила анализа.

Лучшее решение с использованием DMV

К счастью, существует лучшее решение с использованием DMV sys.dm_exec_cached_plans, sys.dm_exec_sql_text и sys.dm_exec_text_query_plan. Анализируя сохраненные в системе планы запросов, мы можем получить ценную информацию о подсказках, используемых в запросах.

Вот простой пример для получения запроса и текстовой версии плана для всех сохраненных планов:

SELECT t.[text], qp.query_plan 
FROM sys.dm_exec_cached_plans AS p
CROSS APPLY sys.dm_exec_sql_text(p.plan_handle) AS t
CROSS APPLY sys.dm_exec_text_query_plan(p.plan_handle, 0, -1) AS qp;

Изучая планы запросов, мы можем определить подсказки, изучая XML-вывод. Некоторые распространенные подсказки, которые можно получить из XML, включают FORCESEEK, FORCESCAN, NOEXPAND и MAXDOP.

Получение подсказок запроса с использованием DMV

Чтобы получить запросы с определенными подсказками, мы можем изменить предыдущий запрос, чтобы включить дополнительные столбцы, указывающие наличие каждой подсказки:

SELECT [Query] = t.[text], [Database] = DB_NAME(t.dbid), qp.query_plan,
    [ForceSeek]  = CASE WHEN qp.query_plan   LIKE '%ForceSeek="1"%'                 THEN 1 ELSE 0 END,
    [ForceScan]  = CASE WHEN qp.query_plan   LIKE '%ForceScan="1"%'                 THEN 1 ELSE 0 END,
    [NoExpand]   = CASE WHEN qp.query_plan   LIKE '%NoExpandHint="1"%'              THEN 1 ELSE 0 END,
    [ForceIndex] = CASE WHEN qp.query_plan   LIKE '%ForcedIndex="1" ForceSeek="1"%' THEN 1 ELSE 0 END,
    [NoLock]     = CASE WHEN UPPER(t.[text]) LIKE '%NOLOCK%'                        THEN 1 ELSE 0 END,
    [MaxDop]     = CASE WHEN qp.query_plan   LIKE '%<QueryPlan%[^<]%"MaxDopSet%' 
                       AND UPPER(t.[text])   LIKE '%MAXDOP%'                        THEN 1 ELSE 0 END
FROM 
    sys.dm_exec_cached_plans AS p
    CROSS APPLY sys.dm_exec_sql_text(p.plan_handle) AS t
    CROSS APPLY sys.dm_exec_text_query_plan(p.plan_handle, 0, -1) AS qp
WHERE 
    t.[text] NOT LIKE '%dm_exec_cached_plans%' -- чтобы исключить этот запрос из результата
    AND
    (
      qp.query_plan LIKE '%ForceSeek="1"%'
      OR qp.query_plan LIKE '%Forcescan="1"%'
      OR qp.query_plan LIKE '%NoExpandHint="1"%'
      OR qp.query_plan LIKE '%ForcedIndex="1" ForceSeek="1"%'
      OR UPPER(t.[text]) LIKE '%NOLOCK%'
   OR (qp.query_plan LIKE '%<QueryPlan%[^<]%"MaxDopSet%' AND UPPER(t.[text]) LIKE '%MAXDOP%')
    );

Этот запрос обеспечивает высокую точность в определении запросов с подсказками. Однако он может давать ложные срабатывания для запросов с подсказками, упомянутыми в комментариях или именах таблиц. Важно помнить об этих ограничениях при анализе результатов.

Соображения и предостережения

При использовании этого метода следует учитывать несколько соображений и предостережений:

  • Некоторые подсказки, такие как OPTION (FORCE ORDER) или подсказки соединения, не отображаются в детерминированном виде в плане запроса. Для идентификации этих подсказок может потребоваться анализ текста запроса.
  • DMV отображают только планы, которые в настоящее время находятся в кэше. Планы могут быть удалены или удалены при перезапуске сервера или выполнении DBCC FREEPROCCACHE.
  • Некоторые подсказки, такие как OPTION (RECOMPILE), предотвращают кэширование плана вообще.
  • Если включена настройка оптимизации для рабочих нагрузок ad hoc, запросы, связанные с планами однократного использования, могут быть недоступны.

Вывод

Используя DMV, мы можем эффективно инвентаризировать запросы с подсказками в нашей системе SQL Server, не прибегая к грубым методам, таким как трассировка на стороне сервера. Анализируя планы запросов, мы можем получить ценную информацию о подсказках, используемых в запросах. Однако важно знать ограничения и предостережения этого подхода.

Используя мощь DMV, администраторы баз данных могут получить представление о выполняемых запросах в их системе SQL Server и принимать обоснованные решения для оптимизации производительности и устранения проблем.

Click to rate this post!
[Total: 0 Average: 0]

Let's work together

Send us a message or book free introductory meeting with us using button below.