Как получить План выполнения запроса?

в Microsoft SQL Server как я могу получить план выполнения запроса для запроса / хранимой процедуры?

9 ответов


существует ряд способов получения плана выполнения, который будет зависеть от ваших обстоятельств. Обычно для получения плана можно использовать среду SQL Server Management Studio, однако если по какой-либо причине не удается выполнить запрос в среде SQL Server Management Studio, может оказаться полезным получить план с помощью профилировщика SQL Server или путем проверки кэша плана.

метод 1-использование SQL Server Management Studio

SQL Server поставляется с пара аккуратных функций, которые позволяют очень легко захватить план выполнения, просто убедитесь, что пункт меню" включить фактический план выполнения "(находится в меню" запрос") отмечен галочкой и запустите запрос как обычно.

Include Action Execution Plan menu item

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

exec p_Example 42

когда ваш запрос завершится, вы увидите дополнительную вкладку под названием "План выполнения" появится в области результатов. Если вы выполнили много операторов, вы можете увидеть много планов, отображаемых на этой вкладке.

Screenshot of an Execution Plan

отсюда вы можете проверить план выполнения в SQL Server Management Studio или щелкнуть правой кнопкой мыши по плану и выбрать "Сохранить план выполнения как ..."чтобы сохранить план в файл в формате XML.

Метод 2-использование параметров SHOWPLAN

этот метод очень похож на метод 1 (на самом деле это то, что SQL Server Management Studio делает внутренне), однако я включил его для полноты или если у вас нет SQL Server Management Studio.

перед запуском запроса, выполните команду один из следующих утверждений. Оператор должен быть единственным оператором в пакете, т. е. вы не можете выполнить другой оператор одновременно:

SET SHOWPLAN_TEXT ON
SET SHOWPLAN_ALL ON
SET SHOWPLAN_XML ON
SET STATISTICS PROFILE ON
SET STATISTICS XML ON -- The is the recommended option to use

это параметры подключения, и поэтому вам нужно только запустить это один раз за соединение. С этого момента все операторы run будут сопровождаться дополнительные resultset содержащий ваш план выполнения в нужном формате-просто запустите запрос, как обычно, чтобы увидеть план.

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

SET <<option>> OFF

сравнение форматов плана выполнения

если у вас нет сильного предпочтения, моя рекомендация-использовать . Эта опция эквивалентна Опция "включить фактический план выполнения" в среде SQL Server Management Studio предоставляет максимальную информацию в наиболее удобном формате.

  • SHOWPLAN_TEXT - отображает базовый текст на основе оценочного плана выполнения, без выполнения запроса
  • SHOWPLAN_ALL - отображает текст на основе оценочного плана выполнения с оценками затрат, без выполнения запроса
  • SHOWPLAN_XML - отображает план выполнения на основе XML с оценками затрат, без выполнение запроса. Это эквивалентно "отображать оценочный план выполнения"..."опция в среде SQL Server Management Studio.
  • STATISTICS PROFILE - выполняет запрос и отображает текстовый план фактического выполнения.
  • STATISTICS XML - выполняет запрос и отображает фактический план выполнения на основе XML. Это эквивалентно опции "включить фактический план выполнения" в среде SQL Server Management Studio.

Метод 3-использование SQL Server Профайлер

если вы не можете запустить свой запрос напрямую (или ваш запрос не запускается медленно, когда вы выполняете его напрямую - помните, что мы хотим, чтобы план запроса выполнялся плохо), то вы можете захватить план с помощью трассировки профилировщика SQL Server. Идея состоит в том, чтобы запустить запрос во время выполнения трассировки, которая захватывает одно из событий "Showplan".

обратите внимание, что в зависимости от нагрузки можете использовать этот метод в производственной среде, однако вы должны очевидно, будьте осторожны. Механизмы профилирования SQL Server предназначены для минимизации влияния на базу данных, но это не означает, что не будет любой влияние на производительность. При интенсивном использовании базы данных могут возникнуть проблемы с фильтрацией и определением правильного плана трассировки. Вы должны, очевидно, проверить с вашим DBA, чтобы увидеть, если они счастливы с вами делать это на их драгоценной базе данных!

  1. откройте профилировщик SQL Server и создайте новая трассировка, соединяющаяся с нужной базой данных, в которую требуется записать трассировку.
  2. на вкладке " выбор событий "установите флажок" Показать все события", проверьте строку" производительность "- > "Showplan XML" и запустите трассировку.
  3. пока трассировка запущена, сделайте все, что вам нужно сделать, чтобы запустить медленный запрос.
  4. дождитесь завершения запроса и остановите трассировку.
  5. для сохранения трассировки щелкните правой кнопкой мыши на XML-плане в SQL Server Profiler и выберите " извлечь данные события..."чтобы сохранить план в файл в формате XML.

полученный план эквивалентен параметру "включить фактический план выполнения" в среде SQL Server Management Studio.

метод 4-Проверка кэша запросов

если вы не можете запустить запрос напрямую, а также не можете захватить трассировку профилировщика, вы все равно можете получить оценочный план, проверив кэш плана запроса SQL.

мы осматриваем планирование кэша путем запроса SQL Server DMVs. Ниже приведен базовый запрос, в котором будут перечислены все кэшированные планы запросов (как xml) вместе с их текстом SQL. В большинстве баз данных вам также нужно будет добавить дополнительные предложения фильтрации, чтобы отфильтровать результаты только до планов, которые вас интересуют.

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)

выполнить этот запрос и нажмите на план XML, чтобы открыть план в новом окне-щелкните правой кнопкой мыши и выберите " Сохранить план выполнения как..."чтобы сохранить план в файл формат XML.

Примечания:

потому что есть так много факторов, участвующих (начиная от таблицы и схемы индекса до сохраненных данных и статистики таблицы), вы должны всегда попробуйте получить план выполнения из интересующей вас базы данных (обычно это та, которая испытывает проблемы с производительностью).

вы не можете создать план выполнения для зашифрованных хранимых процедур.

" фактическое "vs" оценено" планы исполнения

An фактический план выполнения-это тот, где SQL Server фактически выполняет запрос, тогда как оценивается план выполнения SQL Server работает, что это б обойтись без выполнения запроса. Хотя логически эквивалентный, фактический план выполнения гораздо полезнее, поскольку он содержит дополнительные сведения и статистику о том, что на самом деле произошло при выполнении запроса. Это необходимо диагностировать проблемы где Оценки SQL-серверов отключены (например, когда статистика устарела).

как интерпретировать план выполнения запроса?

это тема, достойная (бесплатно)книги в своем собственном праве.

Читайте также:


в дополнение к исчерпывающему ответу, уже опубликованному иногда полезно иметь возможность получить доступ к плану выполнения программно для извлечения информации. Пример кода ниже.

DECLARE @TraceID INT
EXEC StartCapture @@SPID, @TraceID OUTPUT
EXEC sp_help 'sys.objects' /*<-- Call your stored proc of interest here.*/
EXEC StopCapture @TraceID

пример StartCapture определение

CREATE PROCEDURE StartCapture
@Spid INT,
@TraceID INT OUTPUT
AS
DECLARE @maxfilesize BIGINT = 5
DECLARE @filepath NVARCHAR(200) = N'C:\trace_' + LEFT(NEWID(),36)

EXEC sp_trace_create @TraceID OUTPUT, 0, @filepath, @maxfilesize, NULL 

exec sp_trace_setevent @TraceID, 122, 1, 1
exec sp_trace_setevent @TraceID, 122, 22, 1
exec sp_trace_setevent @TraceID, 122, 34, 1
exec sp_trace_setevent @TraceID, 122, 51, 1
exec sp_trace_setevent @TraceID, 122, 12, 1
-- filter for spid
EXEC sp_trace_setfilter @TraceID, 12, 0, 0, @Spid
-- start the trace
EXEC sp_trace_setstatus @TraceID, 1

пример StopCapture определение

CREATE  PROCEDURE StopCapture
@TraceID INT
AS
WITH  XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' as sql), 
      CTE
     as (SELECT CAST(TextData AS VARCHAR(MAX)) AS TextData,
                ObjectID,
                ObjectName,
                EventSequence,
                /*costs accumulate up the tree so the MAX should be the root*/
                MAX(EstimatedTotalSubtreeCost) AS EstimatedTotalSubtreeCost
         FROM   fn_trace_getinfo(@TraceID) fn
                CROSS APPLY fn_trace_gettable(CAST(value AS NVARCHAR(200)), 1)
                CROSS APPLY (SELECT CAST(TextData AS XML) AS xPlan) x
                CROSS APPLY (SELECT T.relop.value('@EstimatedTotalSubtreeCost',
                                            'float') AS EstimatedTotalSubtreeCost
                             FROM   xPlan.nodes('//sql:RelOp') T(relop)) ca
         WHERE  property = 2
                AND TextData IS NOT NULL
                AND ObjectName not in ( 'StopCapture', 'fn_trace_getinfo' )
         GROUP  BY CAST(TextData AS VARCHAR(MAX)),
                   ObjectID,
                   ObjectName,
                   EventSequence)
SELECT ObjectName,
       SUM(EstimatedTotalSubtreeCost) AS EstimatedTotalSubtreeCost
FROM   CTE
GROUP  BY ObjectID,
          ObjectName  

-- Stop the trace
EXEC sp_trace_setstatus @TraceID, 0
-- Close and delete the trace
EXEC sp_trace_setstatus @TraceID, 2
GO

предполагая, что вы используете Microsoft SQL Server Management Studio

  • на Расчетный План Запроса вы можете нажать Ctrl + L или следующая кнопка.

enter image description here

  • на Фактический План Запроса, вы можете нажать сочетания клавиш Ctrl + М или следующая кнопка перед выполнением запрос.

enter image description here

  • на Живой План Запроса, (только в SSMS 2016) перед выполнением запроса используйте следующую кнопку.

enter image description here


помимо методов, описанных в предыдущих ответах, вы также можете использовать бесплатный просмотрщик планов выполнения и инструмент оптимизации запросов План ApexSQL (С которым я недавно столкнулся).

вы можете установить и интегрировать план ApexSQL в SQL Server Management Studio, поэтому планы выполнения можно просматривать непосредственно из SSMS.

просмотр оценочных планов выполнения в Apexsql Plan

  1. выберите Новый Запрос кнопка в SSMS и вставить текст запроса в текстовом окне запроса. Щелкните правой кнопкой мыши и выберите в контекстном меню опцию "отобразить оценочный план выполнения".

New Query button in SSMS

  1. диаграммы плана выполнения будут показаны на вкладке план выполнения в разделе Результаты. Затем щелкните правой кнопкой мыши план выполнения и в контекстном меню выберите " Открыть в плане ApexSQL" выбор.

Execution Plan

  1. оценочный план выполнения будет открыт в Apexsql Plan и может быть проанализирован для оптимизации запросов.

Estimated execution plan

просмотр фактических планов выполнения в Apexsql Plan

чтобы просмотреть фактический план выполнения запроса, перейдите ко второму шагу, упомянутому ранее, но теперь, после отображения расчетного плана, нажмите кнопку Кнопка" фактический " из основной панели ленты в плане ApexSQL.

click the “Actual” button from the main ribbon bar

после нажатия кнопки "фактический" фактический план выполнения будет показан с подробным предварительным просмотром параметров затрат вместе с другими данными плана выполнения.

Actual execution plan

более подробную информацию о просмотре планов выполнения можно найти, следуя этой ссылке.


мой любимый инструмент для получения и глубокого анализа планов выполнения запросов -среда SQL часового плана Обозреватель. Это гораздо более удобный, удобный и всеобъемлющий для детального анализа и визуализации планов выполнения, чем SSMS.

вот пример скриншота для вас, чтобы иметь представление о том, какая функциональность предлагается инструментом:

SQL Sentry Plan Explorer window screen shot

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

кроме того, я не заметил никаких ограничений его бесплатной версии, которая мешает использовать его на ежедневной основе или заставляет вас покупать версию Pro в конечном итоге. Итак, если вы предпочитаете придерживаться бесплатной версии, ничто не запрещает вам это делать.

обновление: (спасибо Мартин Смит) план Explorer теперь бесплатно! См.http://www.sqlsentry.com/products/plan-explorer/sql-server-query-view для деталей.


планы запросов можно получить из расширенного сеанса событий через query_post_execution_showplan событие. Вот пример сеанса XEvent:

/*
    Generated via "Query Detail Tracking" template.
*/
CREATE EVENT SESSION [GetExecutionPlan] ON SERVER 
ADD EVENT sqlserver.query_post_execution_showplan(
    ACTION(package0.event_sequence,sqlserver.plan_handle,sqlserver.query_hash,sqlserver.query_plan_hash,sqlserver.session_id,sqlserver.sql_text,sqlserver.tsql_frame,sqlserver.tsql_stack)),

/* Remove any of the following events (or include additional events) as desired. */
ADD EVENT sqlserver.error_reported(
    ACTION(package0.event_sequence,sqlserver.client_app_name,sqlserver.database_id,sqlserver.plan_handle,sqlserver.query_hash,sqlserver.query_plan_hash,sqlserver.session_id,sqlserver.sql_text,sqlserver.tsql_frame,sqlserver.tsql_stack)
    WHERE ([package0].[greater_than_uint64]([sqlserver].[database_id],(4)) AND [package0].[equal_boolean]([sqlserver].[is_system],(0)))),
ADD EVENT sqlserver.module_end(SET collect_statement=(1)
    ACTION(package0.event_sequence,sqlserver.client_app_name,sqlserver.database_id,sqlserver.plan_handle,sqlserver.query_hash,sqlserver.query_plan_hash,sqlserver.session_id,sqlserver.sql_text,sqlserver.tsql_frame,sqlserver.tsql_stack)
    WHERE ([package0].[greater_than_uint64]([sqlserver].[database_id],(4)) AND [package0].[equal_boolean]([sqlserver].[is_system],(0)))),
ADD EVENT sqlserver.rpc_completed(
    ACTION(package0.event_sequence,sqlserver.client_app_name,sqlserver.database_id,sqlserver.plan_handle,sqlserver.query_hash,sqlserver.query_plan_hash,sqlserver.session_id,sqlserver.sql_text,sqlserver.tsql_frame,sqlserver.tsql_stack)
    WHERE ([package0].[greater_than_uint64]([sqlserver].[database_id],(4)) AND [package0].[equal_boolean]([sqlserver].[is_system],(0)))),
ADD EVENT sqlserver.sp_statement_completed(SET collect_object_name=(1)
    ACTION(package0.event_sequence,sqlserver.client_app_name,sqlserver.database_id,sqlserver.plan_handle,sqlserver.query_hash,sqlserver.query_plan_hash,sqlserver.session_id,sqlserver.sql_text,sqlserver.tsql_frame,sqlserver.tsql_stack)
    WHERE ([package0].[greater_than_uint64]([sqlserver].[database_id],(4)) AND [package0].[equal_boolean]([sqlserver].[is_system],(0)))),
ADD EVENT sqlserver.sql_batch_completed(
    ACTION(package0.event_sequence,sqlserver.client_app_name,sqlserver.database_id,sqlserver.plan_handle,sqlserver.query_hash,sqlserver.query_plan_hash,sqlserver.session_id,sqlserver.sql_text,sqlserver.tsql_frame,sqlserver.tsql_stack)
    WHERE ([package0].[greater_than_uint64]([sqlserver].[database_id],(4)) AND [package0].[equal_boolean]([sqlserver].[is_system],(0)))),
ADD EVENT sqlserver.sql_statement_completed(
    ACTION(package0.event_sequence,sqlserver.client_app_name,sqlserver.database_id,sqlserver.plan_handle,sqlserver.query_hash,sqlserver.query_plan_hash,sqlserver.session_id,sqlserver.sql_text,sqlserver.tsql_frame,sqlserver.tsql_stack)
    WHERE ([package0].[greater_than_uint64]([sqlserver].[database_id],(4)) AND [package0].[equal_boolean]([sqlserver].[is_system],(0)))) 
ADD TARGET package0.ring_buffer
WITH (MAX_MEMORY=4096 KB,EVENT_RETENTION_MODE=ALLOW_SINGLE_EVENT_LOSS,MAX_DISPATCH_LATENCY=30 SECONDS,MAX_EVENT_SIZE=0 KB,MEMORY_PARTITION_MODE=NONE,TRACK_CAUSALITY=ON,STARTUP_STATE=OFF)
GO

после создания сеанса (в SSMS) перейдите в Обозреватель объектов и углубитесь в Управление | расширенные события | сеансы. Щелкните правой кнопкой мыши сеанс "GetExecutionPlan" и запустите его. Щелкните его правой кнопкой мыши и выберите "Watch Live Data".

далее откройте новое окно запроса и выполните один или несколько запросов. Вот Данных AdventureWorks:

USE AdventureWorks;
GO

SELECT p.Name AS ProductName, 
    NonDiscountSales = (OrderQty * UnitPrice),
    Discounts = ((OrderQty * UnitPrice) * UnitPriceDiscount)
FROM Production.Product AS p 
INNER JOIN Sales.SalesOrderDetail AS sod
    ON p.ProductID = sod.ProductID 
ORDER BY ProductName DESC;
GO

через минуту или две вы увидите некоторые результаты на вкладке "GetExecutionPlan: Live Data". Щелкните одно из событий query_post_execution_showplan в сетке, а затем перейдите на вкладку "план запроса" под сеткой. Он должен выглядеть примерно так:

enter image description here

редактировать: код XEvent и снимок экрана были созданы из SQL / SSMS 2012 w / SP2. Если вы используете SQL 2008 / R2, вы может иметь возможность настроить скрипт, чтобы заставить его работать. Но в этой версии нет GUI, поэтому вам придется извлечь XML-файл showplan, сохранить его как *.файл sqlplan и откройте его в SSMS. Это громоздко. XEvents не существовал в SQL 2005 или более ранних версиях. Итак, если вы не на SQL 2012 или более поздней версии, я настоятельно рекомендую один из других ответов, размещенных здесь.


начиная с SQL Server 2016+, функция хранилища запросов была введена для мониторинга производительности. Он обеспечивает понимание выбора и производительности плана запроса. Это не полная замена трассировки или расширенных событий, но поскольку она развивается от версии к версии, мы можем получить полнофункциональное хранилище запросов в будущих выпусках SQL Server. Основной поток запросов

  1. существующие компоненты SQL Server взаимодействуют с хранилищем запросов, используя хранилище запросов Менеджер.
  2. Query Store Manager определяет, какой магазин должен использоваться, а затем передает выполнение в этот магазин (статистика планирования или выполнения или статистика ожидания запроса)
    • Plan Store-сохранение информации о плане выполнения
    • Runtime Stats Store-сохранение информации статистики выполнения
    • Query Wait Stats Store-сохранение информации статистики ожидания.
  3. план, статистика выполнения и магазин ожидания использует запрос Хранить как расширение SQL Server.

enter image description here

  1. включение хранилища запросов: хранилище запросов работает на уровне базы данных на сервере.

    • магазин запросов не активен для новых баз данных по умолчанию.
    • вы не можете включить хранилище запросов для мастера или

здесь одна важная вещь, котор нужно знать в дополнение ко всему сказанному раньше.

планы запросов часто слишком сложны, чтобы быть представленными встроенным типом столбца XML, который имеет ограничение 127 уровней вложенных элементов. Это одна из причин, почему sys.dm_exec_query_plan может вернуться NULL или даже выбросить ошибку в более ранних версиях MS SQL, поэтому обычно безопаснее использовать sys.dm_exec_text_query_plan вместо этого. Последний также есть полезная бонусная функция выбора план для конкретного заявления, а не вся партия. Вот как вы используете его для просмотра планов для текущих запущенных операторов:

SELECT p.query_plan
FROM sys.dm_exec_requests AS r
OUTER APPLY sys.dm_exec_text_query_plan(
                r.plan_handle,
                r.statement_start_offset,
                r.statement_end_offset) AS p

текстовый столбец в результирующей таблице, однако, не очень удобен по сравнению с XML-столбцом. Чтобы иметь возможность нажать на результат, который будет открыт в отдельной вкладке в виде диаграммы, без необходимости сохранять его содержимое в файл, вы можете использовать небольшой трюк (помните, что вы не можете просто использовать CAST(... AS XML)), хотя это будет работать только для одной строки:

SELECT Tag = 1, Parent = NULL, [ShowPlanXML!1!!XMLTEXT] = query_plan
FROM sys.dm_exec_text_query_plan(
                -- set these variables or copy values
                -- from the results of the above query
                @plan_handle,
                @statement_start_offset,
                @statement_end_offset)
FOR XML EXPLICIT

Как и в SQL Server Management Studio (уже объяснено), это также возможно с Datagrip, как объяснено здесь.

  1. щелкните правой кнопкой мыши инструкцию SQL и выберите объяснить план.
  2. в области вывод щелкните план.
  3. по умолчанию отображается древовидное представление запроса. Чтобы увидеть план запроса, щелкните значок показать визуализацию или нажмите Ctrl + Shift+Alt+U