SQL Server如何查看存储过程的执行计划
有时候,我们需要查看存储过程的执行计划,那么我们有什么方式获取存储过程的历史执行计划或当前的执行计划呢? 下面总结一下获取存储过程的执行计划的方法。
1:我们可以通过下面脚本查看存储过程的执行计划,但是有时候,你会发现这种方式并不总是能够获取到存储过程的执行计划。
SELECT
d.object_id ,
DB_NAME(d.database_id) DBName ,
OBJECT_NAME(object_id, database_id) 'SPName' ,
d.cached_time ,
d.last_execution_time ,
d.total_elapsed_time/1000000 AS total_elapsed_time,
d.total_elapsed_time / d.execution_count/1000000
AS [avg_elapsed_time] ,
d.last_elapsed_time/1000000 AS last_elapsed_time,
d.execution_count ,
d.total_physical_reads ,
d.last_physical_reads ,
d.total_logical_writes ,
d.last_logical_reads ,
et.text SQLText ,
eqp.query_plan executionplan
FROM sys.dm_exec_procedure_stats AS d
CROSS APPLY sys.dm_exec_sql_text(d.sql_handle) et
CROSS APPLY sys.dm_exec_query_plan(d.plan_handle) eqp
WHERE OBJECT_NAME(object_id, database_id) = 'xxxx'
ORDER BY [total_worker_time] DESC;
有时候使用这种方式并不能获取存储过程的执行计划,脚本查询出来的结果,query_plan字段为NULL值,那么为什么是NULL值呢?这个是因为有一些限制或条件的缘故,官方文档的解释如下:
Under the following conditions, no Showplan output is returned in the query_plan column of the returned table for sys.dm_exec_query_plan:
· If the query plan that is specified by using plan_handle has been evicted from the plan cache, the query_plan column of the returned table is null. For example, this condition may occur if there is a time delay between when the plan handle was captured and when it was used with sys.dm_exec_query_plan.
· Some Transact-SQL statements are not cached, such as bulk operation statements or statements containing string literals larger than 8 KB in size. XML Showplans for such statements cannot be retrieved by using sys.dm_exec_query_plan unless the batch is currently executing because they do not exist in the cache.
· If a Transact-SQL batch or stored procedure contains a call to a user-defined function or a call to dynamic SQL, for example using EXEC (string), the compiled XML Showplan for the user-defined function is not included in the table returned by sys.dm_exec_query_plan for the batch or stored procedure. Instead, you must make a separate call to sys.dm_exec_query_plan for the plan handle that corresponds to the user-defined function.
When an ad hoc query uses simple or forced parameterization, the query_plan column will contain only the statement text and not the actual query plan. To return the query plan, call sys.dm_exec_query_plan for the plan handle of the prepared parameterized query. You can determine whether the query was parameterized by referencing the sql column of the sys.syscacheobjects view or the text column of the sys.dm_exec_sql_text dynamic management view.
在以下情况下,sys.dm_exec_query_plan的返回表的query_plan列为空值(query_plan列中未返回Showplan输出):
· 通过使用plan_handle查询指定的查询计划(query plan),如果plan_handle已从计划缓存中踢出(逐出),返回的表的query_plan列为null。 例如,如果在捕获计划句柄与将其与sys.dm_exec_query_plan一起使用之间存在时间延迟,则可能会出现这种情况。
· 有些Transact-SQL语句不会cached,例如大容量操作语句(bulk operation statements)或包含大于8 KB的字符串大小的SQL语句。无法使用sys.dm_exec_query_plan检索此类语句的XML Showplans,除非批处理当前正在执行,因为它们不存在于缓存中。
· 如果Transact-SQL批处理或存储的过程包含对用户定义函数的调用或执行动态SQL,例如使用 EXEC (字符串),则用户定义函数的已编译XML Showplan不包含在返回的表中通过sys.dm_exec_query_plan获取批处理或存储过程。相反,您必须单独调用sys.dm_exec_query_plan以获取与用户定义函数对应的计划句柄。
当即席查询使用简单或强制参数化时,query_plan列将包含仅语句文本,而不是实际查询计划。 若要返回查询计划,请调用sys.dm_exec_query_plan准备参数化查询的计划句柄。 您可以确定查询是否已参数化通过引用sql的列sys.syscacheobjects视图或文本列sys.dm_exec_sql_text动态管理视图。
注意:sys.dm_exec_query_plan返回的是实际执行计划。
2:使用SET SHOWPLAN_ALL ON 和SET SHOWPLAN_XML ON获取存储过程的执行计划。
如下所示,在AdventureWorks2014数据库中,查看存储过程[dbo].[uspGetEmployeeManagers] 的执行计划
SET SHOWPLAN_ALL ON
GO
SET FMTONLY ON
GO
EXEC dbo].[uspGetEmployeeManagers] 242;
GO
SET FMTONLY OFF
GO
SET SHOWPLAN_ALL OFF
GO
SET SHOWPLAN_ALL ON
GO
EXEC [dbo].[uspGetEmployeeManagers] 242;
GO
SET SHOWPLAN_ALL OFF;
GO
SET SHOWPLAN_XML ON
GO
EXEC [dbo].[uspGetEmployeeManagers] 242;
GO
SET SHOWPLAN_XML OFF;
GO
这种方式获取的是存储过程的预估执行计划,并不是实际执行计划,而且这种方式不会执行存储过程。另外,如果存储过程中存在临时表,那么就会出错。出现类似下面这样的错误:
Msg 208, Level 16, State 0, Procedure IntegrityTesting, Line 57
Invalid object name '#DbToCheck'.
3:SSMS中选中执行存储过程的脚本后,使用快捷方式CTRL+L或勾选“Display Estimated Execution Plan”获取存储过程的执行计划。
这种方式其实只是方式2(命令方式)的图形界面操作而已。所以此处不做展开
4:SSMS中使用快捷方式CTRL+M或勾选“Include Actual Execution plan”后,执行存储过程后,就能看到实际执行计划
这种方式看到的是存储过程的实际执行计划,但是很多时候,这种方式适用于开发、测试环境,但是我们在生产环境诊断问题时,这种方式并不适用。因为有时候存储过程会有DML操作,会修改数据。
5:SET STATISTICS XML 或SET STATISTICS PROFILE查看实际执行计划。
SET STATISTICS XML ON
GO
EXEC [dbo].[uspGetEmployeeManagers] 242;
GO
SET STATISTICS XML OFF;
GO
或
SET STATISTICS PROFILE ON
GO
EXEC [dbo].[uspGetEmployeeManagers] 242;
GO
SET STATISTICS PROFILE OFF;
GO
这个方式会执行存储过程。所以弊端上面也说过,有时候生产环境并不适用。
7:适用SQL Server Profile跟踪获取存储过程的实际执行计划
1: 打开SQL Server Profiler工具
2:在文件菜单,选择开启一个新的跟踪,跟踪对应的数据库服务器
3:“Events Section”选项卡中,"Use the template“选择“blank”
4: 然后在Performance节点,勾选相关字段。“Column Filter"设置过滤选项。例如只跟踪捕获某个数据库的某个存储过程的执行计划。如下例子所示


总结:我们可以使用上面方式获取存储过程的预估执行计划或实际执行计划。各有利弊,主要看使用场景,如果在生产环境诊断问题,优化SQL时,建议使用方式1 或 SQL Server Profiler, 因为有时候预估的执行计划,可能跟实际执行计划有出入,以及参数嗅探问题等等。
参考资料:
SQL Server如何查看存储过程的执行计划的更多相关文章
- SQL Server INSET/UPDATE/DELETE的执行计划
DML操作符包括增删改查等操作方式. insert into Person.Address (AddressLine1, AddressLine2, City, StateProvinceID, Po ...
- SQL Server 性能调优 之执行计划(Execution Plan)调优
SQL Server 存在三种 Join 策略:Hash Join,Merge Join,Nested Loop Join. Hash Join:用来处理没有排过序/没有索引的数据,它在内存中把 Jo ...
- 理解性能的奥秘——应用程序中慢,SSMS中快(2)——SQL Server如何编译存储过程
本文属于<理解性能的奥秘--应用程序中慢,SSMS中快>系列 接上文:理解性能的奥秘--应用程序中慢,SSMS中快(1)--简介 本文介绍SQL Server如何编译存储过程并使用计划缓存 ...
- sql server内置存储过程、查看系统信息
1.检索关键字:sql server内置存储过程,sql server查看系统信息 2.查看磁盘空间:EXEC master.dbo.xp_fixeddrives , --查看各个数据库所在磁盘情况S ...
- TFDStoredProc执行sql server的部分存储过程报错,有的是好的。
TFDStoredProc执行sql server的部分存储过程报错,有的是好的. Invalid character value for cast specification 暂时无解.用fdque ...
- PL/SQL Developer 查看查询的执行计划
https://zhuanlan.zhihu.com/p/65771352 通过 PL/SQL Developer 查看查询的执行计划 1 什么是执行计划 执行计划是一条查询语句在 Oracle 中的 ...
- Sql Server系列:存储过程
1 存储过程简介 存储过程是使用T-SQL代码编写的代码段.在存储过程中,可以声明变量.执行条件判断语句等其他编程功能.在MS SQL Server 2012中存储过程主要分三类:系统存储过程.自定义 ...
- Sql Server 常用系统存储过程大全
-- 来源于网络 -- 更详细的介结参考联机帮助文档 xp_cmdshell --*执行DOS各种命令,结果以文本行返回. xp_fixeddrives --*查询各磁盘/分区可用空间 xp_logi ...
- SQL点滴27—性能分析之执行计划
原文:SQL点滴27-性能分析之执行计划 一直想找一些关于SQL语句性能调试的权威参考,但是有参考未必就能够做好调试的工作.我深信实践中得到的经验是最珍贵的,书本知识只是一个引导.本篇来源于<I ...
随机推荐
- Linux-换yum源
1.打开centos的yum文件夹 cd /etc/yum.repos.d/ 2.用wget下载repo文件 wget http://mirrors.aliyun.com/repo/Centos-7. ...
- 约瑟夫问题 -- python实现
问题描述 N个人围成一个圈, 从第一个人开始报数, 报到M的人出圈, 剩下的人继续从1开始报数, 报到M的人出圈;如此往复, 直到所有人出圈. 列表解决 def solution_list(n, m) ...
- Nginx安装与运行
目录 Nginx安装与运行 安装Nginx 运行 注意事项 Nginx安装与运行 安装Nginx 在Nginx官网下载对应的nginx包(推荐使用稳定版[Stable version]) 上传ngin ...
- PHP中使用date获取上月最后一天出现的问题
上次做项目时,发现一个问题,这里记录一下: 问题: 在使用date函数获取上一个月最后一天或下个月最后一天时,如果当前日期是31号,获取的数据有问题. // 2019-12-01 正确应该是 2019 ...
- SpringCloud断路器(Hystrix)
一.为什么需要 Hystrix? 在微服务架构中,我们将业务拆分成一个个的服务,服务与服务之间可以相互调用(RPC).为了保证其高可用,单个服务又必须集群部署.由于网络原因或者自身的原因,服务并不能保 ...
- 8年开发老司机告诉你啥是java开发?如何学?学习什么内容?
什么是Java? 我从Java的官网上抄下来下面这段话:97% 的企业桌面运行 Java美国有 89% 的桌面(或计算机)运行 Java全球有 900 万 Java 开发人员开发人员的头号选择排名第一 ...
- SQLserver还原失败(数据库正在使用,无法获得对数据库的独占访问权)
问题描述: Sql server还原失败(数据库正在使用,无法获得对数据库的独占访问权) 数据库还原的时候还有其他进程连在上面,导致无法获得独占造成的. 这个问题的原因在于有用户连接了当前要做还原的数 ...
- CAS与ABA问题产生和优雅解决
本人免费整理了Java高级资料,涵盖了Java.Redis.MongoDB.MySQL.Zookeeper.Spring Cloud.Dubbo高并发分布式等教程,一共30G,需要自己领取.传送门:h ...
- springcloud~配置中心~对敏感信息加密
简介 RSA非对称加密有着非常强大的安全性,HTTPS的SSL加密就是使用这种方法进行HTTPS请求加密传输的.因为RSA算法会涉及Private Key和Public Key分别用来加密和解密,所以 ...
- angular cli 使用echarts
1.安装库 npm install typings echarts --global npm install ngx-echarts --save npm install @types/echarts ...