在Microsoft SQL Server中,如何获取查询/存储过程的查询执行计划?
#1楼
我最喜欢的用于获取和深入分析查询执行计划的工具是SQL Sentry Plan Explorer 。 与SSMS相比,它对执行计划的详细分析和可视化更加友好,方便和全面。
这是一个示例屏幕快照,可让您大致了解该工具提供的功能:
这只是该工具中可用的视图之一。 注意应用程序窗口底部的一组选项卡,它使您可以获取不同类型的执行计划表示形式以及有用的其他信息。
此外,我还没有注意到其免费版的任何限制,这些限制会阻止其日常使用或迫使您最终购买Pro版本。 因此,如果您更喜欢免费版,那么没有什么可以阻止您这样做的。
更新:(感谢Martin Smith )Plan Explorer现在是免费的! 有关详细信息,请参见http://www.sqlsentry.com/products/plan-explorer/sql-server-query-view 。
#2楼
可以通过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:实时数据”选项卡中看到一些结果。 单击网格中的query_post_execution_showplan事件之一,然后单击网格下方的“查询计划”选项卡。 它看起来应该类似于:
编辑 :XEvent代码和屏幕截图是从带有SP2的SQL / SSMS 2012中生成的。 如果您使用SQL 2008 / R2,您可能能够调整的脚本,使其运行。 但是该版本没有GUI,因此您必须提取showplan XML,将其另存为* .sqlplan文件,然后在SSMS中打开它。 太麻烦了 XEvents在SQL 2005或更早版本中不存在。 因此,如果您不使用SQL 2012或更高版本,则强烈建议您在此处发布其他答案之一。
#3楼
假设您正在使用Microsoft SQL Server Management Studio
- 对于估算查询计划,您可以按Ctrl + L或以下按钮。
- 对于“ 实际查询计划” ,可以在执行查询之前按Ctrl + M或以下按钮。
- 对于实时查询计划 ,(仅在SSMS 2016中)在执行查询之前使用以下按钮。
#4楼
除了先前答案中描述的方法之外,您还可以使用免费的执行计划查看器和查询优化工具ApexSQL Plan (我最近接触过)。
您可以将ApexSQL Plan安装并集成到SQL Server Management Studio中,以便可以直接从SSMS查看执行计划。
在ApexSQL计划中查看估计的执行计划
- 单击SSMS中的“ 新建查询”按钮,然后将查询文本粘贴到查询文本窗口中。 右键单击并从上下文菜单中选择“显示估计的执行计划”选项。
- 执行计划图将显示在结果部分的“执行计划”选项卡中。 接下来,右键单击执行计划,然后在上下文菜单中选择“在ApexSQL计划中打开”选项。
- 估计执行计划将在ApexSQL计划中打开,可以对其进行分析以进行查询优化。
在ApexSQL计划中查看实际执行计划
要查看查询的实际执行计划,请从前面提到的第二步继续,但是现在,一旦显示了估算计划,请单击ApexSQL计划主功能区栏中的“实际”按钮。
单击“实际”按钮后,将显示“实际执行计划”,并带有成本参数的详细预览以及其他执行计划数据。
通过以下链接可以找到有关查看执行计划的更多信息。
#5楼
从SQL Server 2016+开始,引入了查询存储功能以监视性能。 它提供有关查询计划选择和性能的见解。 它不是跟踪事件或扩展事件的完整替代品,但是随着版本之间的演进,我们可能会在SQL Server的将来版本中获得功能齐全的查询存储。 查询存储的主要流程
- SQL Server现有组件通过利用查询存储管理器与查询存储进行交互。
- 查询存储管理器确定应使用哪个存储,然后将执行传递给该存储(计划或运行时统计或查询等待统计)
- 计划存储-保留执行计划信息
- 运行时统计信息存储-持久执行统计信息
- 查询等待统计信息存储-持久等待统计信息。
- 计划,运行时统计信息和等待存储使用查询存储作为SQL Server的扩展。
启用查询存储 :查询存储在服务器上的数据库级别工作。
- 默认情况下,查询存储对新数据库无效。
- 您不能为master或
tempdb
数据库启用查询存储。 - 可用的DMV
sys.database_query_store_options
(Transact-SQL)
在查询存储中收集信息 :我们使用查询存储DMV(数据管理视图)从三个存储中收集所有可用信息。
查询计划存储:保留执行计划信息,它负责捕获与查询编译有关的所有信息。
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+中可用
来源:oschina
链接:https://my.oschina.net/stackoom/blog/3190031