Як в Microsoft SQL Server можна отримати план виконання запиту для запиту / збереженої процедури?
Як в Microsoft SQL Server можна отримати план виконання запиту для запиту / збереженої процедури?
Відповіді:
Існує ряд методів отримання плану виконання, який використовуватимуть залежно від ваших обставин. Зазвичай ви можете використовувати студію управління SQL Server для отримання плану, однак якщо з якихось причин ви не можете запустити свій запит у SQL Server Management Studio, то вам може бути корисним отримати план через Profiler SQL Server або перевірити кеш плану.
SQL Server оснащений парою акуратних функцій, які дозволяють легко зафіксувати план виконання, просто переконайтесь, що пункт меню "Включити фактичний план виконання" (знайдений у меню "Запит") і запустити ваш запит як звичайний .
Якщо ви намагаєтеся отримати план виконання для операторів у збереженій процедурі, вам слід виконати збережену процедуру, наприклад:
exec p_Example 42
Після завершення запиту на панелі результатів відобразиться додаткова вкладка під назвою "План виконання". Якщо ви запустили багато заяв, то на цій вкладці може відображатися багато планів.
Звідси ви можете ознайомитись із планом виконання у студії управління SQL Server або клацніть правою кнопкою миші та виберіть "Зберегти план виконання як ...", щоб зберегти план у файлі у форматі XML.
Цей метод дуже схожий на метод 1 (насправді це те, що SQL Server Management Studio робить всередині), проте я включив його для повноти або якщо у вас немає студії управління SQL Server.
Перш ніж запустити запит, запустіть одне із наведених нижче тверджень. Оператор повинен бути єдиним твердженням у пакеті, тобто ви не можете виконати інший оператор одночасно:
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
Це варіанти підключення, і вам потрібно запустити це лише один раз за з'єднання. З цього моменту всі запущені оператори будуть супроводжуватися додатковим набором результатів, що містить ваш план виконання у бажаному форматі - просто запустіть запит так, як зазвичай ви бачили план.
Як тільки ви закінчите, ви можете вимкнути цю опцію за допомогою наступного твердження:
SET <<option>> OFF
Якщо у вас немає сильних переваг, моя рекомендація - використовувати цей STATISTICS XML
варіант. Цей параметр еквівалентний опції "Включити фактичний план виконання" в студії управління SQL Server і надає найбільшу інформацію в найбільш зручному форматі.
SHOWPLAN_TEXT
- Відображає базовий текстовий орієнтовний план виконання, не виконуючи запитSHOWPLAN_ALL
- Відображає текстовий орієнтовний план виконання з оцінкою витрат, не виконуючи запитSHOWPLAN_XML
- Відображає орієнтовний план виконання на основі XML з оцінкою витрат, не виконуючи запит. Це еквівалентно параметру "Відображати передбачуваний план виконання ..." в студії управління SQL Server.STATISTICS PROFILE
- Виконує запит і відображає текстовий фактичний план виконання.STATISTICS XML
- Виконує запит і відображає фактичний план виконання на основі XML. Це еквівалентно опції "Включити фактичний план виконання" в студії управління SQL Server.Якщо ви не можете запустити запит безпосередньо (або ваш запит не запускається повільно, коли ви його виконуєте безпосередньо - пам’ятайте, що ми хочемо, щоб план запиту виконувався погано), тоді ви можете зафіксувати план, використовуючи трасування SQL Server Profiler. Ідея полягає у запуску запиту під час запуску траси, яка фіксує одне із подій "Showplan".
Зауважте, що залежно від навантаження ви можете використовувати цей метод у виробничих умовах, однак, очевидно, слід бути обережними. Механізми профілювання SQL Server розроблені для мінімізації впливу на базу даних, але це не означає, що ніякого впливу на продуктивність не буде . Також у вас можуть виникнути проблеми з фільтрацією та виявленням правильного плану у вашому сліді, якщо ваша база даних не використовується. Ви, очевидно, повинні проконсультуватися у своєї DBA, щоб побачити, чи задоволені вони від вас, роблячи це на своїй дорогоцінній базі даних!
Отриманий вами план еквівалентний опції "Включити фактичний план виконання" в студії управління SQL Server.
Якщо ви не можете запустити запит безпосередньо, а також не можете зафіксувати слід профілера, тоді ви все одно можете отримати приблизний план, перевіривши кеш плану плану запитів SQL.
Ми перевіряємо кеш плану, запитуючи DMV SQL Server . Далі наведено базовий запит, який перелічить усі кешовані плани запитів (у вигляді 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.
Оскільки є так багато факторів (починаючи з таблиці та схеми індексів до даних, що зберігаються, та статистики таблиці), ви завжди повинні намагатися отримати план виконання з цікавої бази даних (як правило, тієї, яка переживає продуктивність). проблема).
Ви не можете зафіксувати план виконання для зашифрованих збережених процедур.
Фактичне виконання плану є один , де SQL Server фактично виконує запит, в той час як оцінюється виконання плану SQL Server працює, що він буде робити без виконання запиту. Хоча логічно еквівалентний, фактичний план виконання є набагато кориснішим, оскільки містить додаткові деталі та статистику того, що насправді сталося під час виконання запиту. Це важливо при діагностуванні проблем, коли оцінки SQL-серверів вимкнено (наприклад, коли застаріла статистика).
Це досить гідна тема (безкоштовно) книги .
SET STATISTICS XML ON
мурашник на початок запиту, а також SET STATISTICS XML OFF|ON
навколишні області, які ви не хочете відображати у плані виводу: я вважаю це корисним, коли запит містить ітерацію (WHILE), яку ви не хочете / не потребуєте бачити в плані виконання (інакше SQL SERVER би відображав його занадто важко і довго).
На додаток до вже викладеної вичерпної відповіді, іноді корисно мати доступ до плану виконання програмно для отримання інформації. Приклад коду для цього наведено нижче.
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
Окрім методів, описаних у попередніх відповідях, ви також можете скористатися вільним переглядачем плану виконання та інструментом оптимізації запитів ApexSQL Plan (на який я нещодавно натрапив).
Ви можете встановити та інтегрувати ApexSQL Plan в SQL Server Management Studio, тому плани виконання можна переглядати безпосередньо з SSMS.
Перегляд передбачуваних планів виконання в плані ApexSQL
Перегляд фактичних планів виконання у плані ApexSQL
Щоб переглянути фактичний план виконання запиту, перейдіть з 2-го кроку, згаданого раніше, але тепер, коли буде показано прогнозований план, натисніть кнопку «Фактичний» на головній стрічці в плані ApexSQL.
Після натискання кнопки «Фактичний» буде показаний фактичний план виконання з детальним переглядом параметрів витрат разом з іншими даними плану виконання.
Більше інформації про перегляд планів виконання можна отримати за цим посиланням .
Моїм улюбленим інструментом для отримання та глибокого аналізу планів виконання запитів є SQL Sentry Plan Explorer . Це набагато більш зручний для користувачів, зручний та всебічний для детального аналізу та візуалізації планів виконання, ніж SSMS.
Ось зразковий знімок екрана, щоб ви мали уявлення про те, яку функціональність пропонує інструмент:
Це лише одне із представлених у цьому інструменті поглядів. Помітьте набір вкладок у нижній частині вікна програми, що дозволяє отримувати різні типи представлення плану виконання та корисну додаткову інформацію.
Крім того, я не помітив жодних обмежень його безкоштовного видання, що заважає використовувати його щодня або змушує вас купувати Pro версію. Отже, якщо ви віддаєте перевагу дотримуватися безкоштовного видання, ніщо не забороняє вам цього робити.
ОНОВЛЕННЯ: (Завдяки Мартіну Сміту ) План Explorer зараз безкоштовний! Докладні відомості див. У розділі http://www.sqlsentry.com/products/plan-explorer/sql-server-query-view .
Speaking of third-party tools
коли ніхто не згадував інструменти сторонніх виробників.
Плани запитів можна отримати з розширеного сеансу подій через 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" і запустіть її. Клацніть його ще раз правою кнопкою миші та виберіть "Дивитися живі дані".
Далі відкрийте нове вікно запитів та запустіть один або кілька запитів. Ось один для 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 у сітці, а потім натисніть на вкладку "План запитів" під сіткою. Це має виглядати приблизно так:
EDIT : Код XEvent і знімки екрану були отримані від SQL / SSMS 2012 Вт / SP2. Якщо ви використовуєте SQL 2008 / R2, можливо , ви зможете налаштувати сценарій, щоб він запустився. Але ця версія не має графічного інтерфейсу, тому вам доведеться витягти XML showplan, зберегти його як * .sqlplan файл і відкрити його в SSMS. Це громіздко. XEvents не існувало в SQL 2005 або раніше. Отже, якщо ви не на SQL 2012 або пізнішої версії, я настійно пропоную один з інших відповідей, розміщених тут.
Починаючи з SQL Server 2016+, для контролю продуктивності була введена функція магазину запитів. Він дає змогу ознайомитись із вибором та роботою плану запитів. Це не повна заміна слідів або розширених подій, але в міру того, як вона розвивається від версії до версії, ми можемо отримати повністю функціональний магазин запитів у майбутніх випусках від SQL Server. Первинний потік магазину запитів
Включення магазину запитів : Магазин запитів працює на рівні бази даних на сервері.
tempdb
бази даних.
sys.database_query_store_options
(Transact-SQL)
Збір інформації в магазині запитів : ми збираємо всю наявну інформацію з трьох магазинів, використовуючи DMV Store Store (Перегляд даних).
Магазин плану запитів: зберігається інформація про план виконання, і він підзвітний за фіксацію всієї інформації, яка пов'язана зі складанням запитів.
sys.query_store_query
(Transact-SQL)sys.query_store_plan
(Transact-SQL)sys.query_store_query_text
(Transact-SQL)
Магазин статистики виконання: зберігається інформація про статистику виконання, і це, мабуть, найбільш часто оновлюваний магазин. Ці статистичні дані представляють дані виконання запитів.
sys.query_store_runtime_stats
(Transact-SQL)
Магазин статистики очікування запитів: зберігається та фіксується інформація про статистику очікування.
sys.query_store_wait_stats
(Transact-SQL)
ПРИМІТКА: Магазин статистики очікування запитів доступний лише у SQL Server 2017+
Як і у студії управління SQL Server (вже пояснено), це можливо також із Datagrip, як пояснено тут .
- Клацніть правою кнопкою миші оператор SQL та виберіть Пояснити план.
- На панелі "Виведення" натисніть "План".
- За замовчуванням ви бачите дерево представлення запиту. Щоб переглянути план запитів, натисніть значок Показати візуалізацію або натисніть Ctrl + Shift + Alt + U
Ось одне важливе, що потрібно знати, окрім всього сказаного раніше.
Плани запитів часто занадто складні, щоб бути представлені вбудованим типом стовпців 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
Ви також можете зробити це через посібник, використовуючи SET STATISTICS XML ON, щоб отримати фактичний план. Я написав це так, що він об'єднує багатопланові плани в один план;
########## BEGIN : SCRIPT VARIABLES #####################
[string]$server = '.\MySQLServer'
[string]$database = 'MyDatabase'
[string]$sqlCommand = 'EXEC sp_ExampleSproc'
[string]$XMLOutputFileName = 'sp_ExampleSproc'
[string]$XMLOutputPath = 'C:\SQLDumps\ActualPlans\'
########## END : SCRIPT VARIABLES #####################
#Set up connection
$connectionString = "Persist Security Info=False;Integrated Security=true;Connection Timeout=0;Initial Catalog=$database;Server=$server"
$connection = new-object system.data.SqlClient.SQLConnection($connectionString)
#Set up commands
$command = new-object system.data.sqlclient.sqlcommand($sqlCommand,$connection)
$command.CommandTimeout = 0
$commandXMLActPlanOn = new-object system.data.sqlclient.sqlcommand("SET STATISTICS XML ON",$connection)
$commandXMLActPlanOff = new-object system.data.sqlclient.sqlcommand("SET STATISTICS XML OFF",$connection)
$connection.Open()
#Enable session XML plan
$result = $commandXMLActPlanOn.ExecuteNonQuery()
#Execute SP and return resultsets into a dataset
$adapter = New-Object System.Data.sqlclient.sqlDataAdapter $command
$dataset = New-Object System.Data.DataSet
$adapter.Fill($dataSet) | Out-Null
#Set up output file name and path
[string]$fileNameDateStamp = get-date -f yyyyMMdd_HHmmss
[string]$XMLOutputFilePath = "$XMLOutputPath$XMLOutputFileName`_$fileNameDateStamp.sqlplan"
#Pull XML plans out of dataset and merge into one multi-statement plan
[int]$cntr = 1
ForEach($table in $dataset.Tables)
{
if($table.Columns[0].ColumnName -eq "Microsoft SQL Server 2005 XML Showplan")
{
[string]$fullXMLPlan = $Table.rows[0]."Microsoft SQL Server 2005 XML Showplan"
if($cntr -eq 1)
{
[regex]$rx = "\<ShowPlanXML xmlns\=.{1,}\<Statements\>"
[string]$startXMLPlan = $rx.Match($fullXMLPlan).Value
[regex]$rx = "\<\/Statements\>.{1,}\<\/ShowPlanXML\>"
[string]$endXMLPlan = $rx.Match($fullXMLPlan).Value
$startXMLPlan | out-file -Append -FilePath $XMLOutputFilePath
}
[regex]$rx = "\<StmtSimple.{1,}\<\/StmtSimple\>"
[string]$bodyXMLPlan = $rx.Match($fullXMLPlan).Value
$bodyXMLPlan | out-file -Append -FilePath $XMLOutputFilePath
$cntr += 1
}
}
$endXMLPlan | out-file -Append -FilePath $XMLOutputFilePath
#Disable session XML plan
$result = $commandXMLActPlanOff.ExecuteNonQuery()
$connection.Close()
Як я пояснив у цій статті , є два типи плану виконання, які ви можете отримати при використанні SQL Server.
Орієнтовний план виконання генерується оптимізатором без запуску запиту SQL.
Для того, щоб отримати орієнтовний план виконання, вам слід включити SHOWPLAN_ALL
налаштування перед виконанням запиту.
УВІМКНЕНО SHOWPLAN_ALL
Тепер, виконуючи наступний запит SQL:
SELECT p.id
FROM post p
WHERE EXISTS (
SELECT 1
FROM post_comment pc
WHERE
pc.post_id = p.id AND
pc.review = 'Bingo'
)
ORDER BY p.title
OFFSET 20 ROWS
FETCH NEXT 10 ROWS ONLY
SQL Server генерує такий розрахунковий план виконання:
| NodeId | Parent | LogicalOp | EstimateRows | EstimateIO | EstimateCPU | AvgRowSize | TotalSubtreeCost | EstimateExecutions |
|--------|--------|----------------------|--------------|-------------|-------------|------------|------------------|--------------------|
| 1 | 0 | NULL | 10 | NULL | NULL | NULL | 0.03374284 | NULL |
| 2 | 1 | Top | 10 | 0 | 3.00E-06 | 15 | 0.03374284 | 1 |
| 4 | 2 | Distinct Sort | 30 | 0.01126126 | 0.000504114 | 146 | 0.03373984 | 1 |
| 5 | 4 | Inner Join | 46.698 | 0 | 0.00017974 | 146 | 0.02197446 | 1 |
| 6 | 5 | Clustered Index Scan | 43 | 0.004606482 | 0.0007543 | 31 | 0.005360782 | 1 |
| 7 | 5 | Clustered Index Seek | 1 | 0.003125 | 0.0001581 | 146 | 0.0161733 | 43 |
Після запуску запиту, який ми зацікавлені в отриманні прогнозованого плану виконання, вам потрібно відключити, оскільки SHOWPLAN_ALL
в іншому випадку поточний сеанс бази даних буде генерувати лише передбачуваний план виконання замість виконання наданих SQL запитів.
SET SHOWPLAN_ALL OFF
У додатку SQL Server Management Studio, ви можете легко отримати приблизний план виконання будь-якого запиту SQL, натиснувши CTRL+L
клавішу швидкого доступу.
Фактичний план виконання SQL генерується оптимізатором при запуску запиту SQL. Якщо статистичні дані таблиці баз даних точні, фактичний план не повинен суттєво відрізнятися від прогнозованого.
Щоб отримати фактичний план виконання на SQL Server, потрібно включити STATISTICS IO, TIME, PROFILE
настройки, як це проілюстровано наступною командою SQL:
SET STATISTICS IO, TIME, PROFILE ON
Тепер при запуску попереднього запиту SQL Server генерує такий план виконання:
| Rows | Executes | NodeId | Parent | LogicalOp | EstimateRows | EstimateIO | EstimateCPU | AvgRowSize | TotalSubtreeCost |
|------|----------|--------|--------|----------------------|--------------|-------------|-------------|------------|------------------|
| 10 | 1 | 1 | 0 | NULL | 10 | NULL | NULL | NULL | 0.03338978 |
| 10 | 1 | 2 | 1 | Top | 1.00E+01 | 0 | 3.00E-06 | 15 | 0.03338978 |
| 30 | 1 | 4 | 2 | Distinct Sort | 30 | 0.01126126 | 0.000478783 | 146 | 0.03338679 |
| 41 | 1 | 5 | 4 | Inner Join | 44.362 | 0 | 0.00017138 | 146 | 0.02164674 |
| 41 | 1 | 6 | 5 | Clustered Index Scan | 41 | 0.004606482 | 0.0007521 | 31 | 0.005358581 |
| 41 | 41 | 7 | 5 | Clustered Index Seek | 1 | 0.003125 | 0.0001581 | 146 | 0.0158571 |
SQL Server parse and compile time:
CPU time = 8 ms, elapsed time = 8 ms.
(10 row(s) affected)
Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'post'. Scan count 0, logical reads 116, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'post_comment'. Scan count 1, logical reads 5, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
(6 row(s) affected)
SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 1 ms.
Після запуску запиту, який ми зацікавлені в отриманні фактичного плану виконання, вам потрібно відключити такі STATISTICS IO, TIME, PROFILE ON
налаштування:
SET STATISTICS IO, TIME, PROFILE OFF
У додатку SQL Server Management Studio, ви можете легко отримати приблизний план виконання будь-якого запиту SQL, натиснувши CTRL+M
клавішу швидкого доступу.
Детальніше про отримання плану виконання під час використання SQL Server див. У цій статті .
Пояснення плану виконання може бути дуже детальним і займає досить багато часу для читання, але підсумовуючи це, якщо ви використовуєте 'пояснити' перед запитом, він повинен дати вам багато інформації, включаючи, які частини були виконані спочатку тощо. якщо ви хочете прочитати трохи детальніше про це, я склав невеликий блог про це, який вказує вам і на правильні відгуки. https://medium.com/swlh/jetbrains-datagrip-explain-plan-ac406772c470