有时候,我们需要查看存储过程的执行计划,那么我们有什么方式获取存储过程的历史执行计划或当前的执行计划呢? 下面总结一下获取存储过程的执行计划的方法。

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, 因为有时候预估的执行计划,可能跟实际执行计划有出入,以及参数嗅探问题等等。

参考资料:

 

https://docs.microsoft.com/zh-cn/sql/relational-databases/system-dynamic-management-views/sys-dm-exec-query-plan-transact-sql?view=sql-server-2017

转载于:https://www.cnblogs.com/kerrycode/p/11102040.html

SQL Server如何查看存储过程的执行计划相关推荐

  1. SQL Server性能调优之执行计划深度剖析 第二节 执行计划第一次实践

    SQL Server性能调优之执行计划深度剖析 第二节 执行计划第一次实践 前言:自从上一篇文章发出之后,收到了很朋友的关注.很多朋友要求多多实践,而不是纯粹的理论.确实,从打算出这个系列开始,我就本 ...

  2. RDS SQL Server - 专题分享 - 巧用执行计划缓存之Table Scan

    背景引入 执行计划中的Table Scan或者是Clustered Index Scan会导致非常低下的查询性能,尤其是对于大表或者超大表.执行计划缓存是SQL Server内存管理中非常重要的特性, ...

  3. 如何在SQL Server 2016中比较查询执行计划

    SQL Server 2016 provides great enhancement capability features for troubleshooting purposes. Some of ...

  4. sql server内置存储过程、查看系统信息

    1.检索关键字:sql server内置存储过程,sql server查看系统信息 2.查看磁盘空间:EXEC master.dbo.xp_fixeddrives , --查看各个数据库所在磁盘情况S ...

  5. 在SQL server中如何定时自动执行存储过程

    在SQL server中如何定时自动执行存储过程 1.首先开启sql代理服务 2.打开sqlserver软件 3.拉开SQL Server 服务菜单 4.右键作业,点击新增作业 5.在一般中添加名称和 ...

  6. Sql Server实用操作-存储过程精解

    CREATE PROCEDURE 创建存储过程,存储过程是保存起来的可以接受和返回用户提供的参数的 Transact-SQL 语句的集合.可以创建一个过程供永久使用,或在一个会话中临时使用(局部临时过 ...

  7. 优化SQL Server的内存占用之执行缓存

    优化SQL Server的内存占用之执行缓存篇 优化SQL Server的内存占用之执行缓存 在论坛上常见有朋友抱怨,说SQL Server太吃内存了.这里笔者根据经验简单介绍一下内存相关的调优知识. ...

  8. Sql Server系列:存储过程

    1 存储过程简介 存储过程是使用T-SQL代码编写的代码段.在存储过程中,可以声明变量.执行条件判断语句等其他编程功能.在MS SQL Server 2012中存储过程主要分三类:系统存储过程.自定义 ...

  9. SQL Server Transact-SQL编程/存储过程/触发器

    1.T-sql语言 数据定义语言DDL对表或视图的操作 数据操纵语言DML对数据进行操作 数据控制语言 其他常用类型:      事务管理语言     流程控制语言  循环  分支  选择     附 ...

最新文章

  1. 在C#中使用代理的方式触发事件
  2. Apache Falcon数据集管理和数据处理平台
  3. MySQL:实用 SQL 语句集合
  4. 客户端渲染换为服务器端渲染_服务器与客户端渲染(AngularJS与服务器端MVC)
  5. ajax调用java程序,从微信小程序到鸿蒙JS开发-JS调用Java
  6. 报错,java.lang.NoSuchMethodException: java.awt.print.Pageable
  7. Springboot 中的header, cookie, session
  8. 九、Linux的网络配置
  9. c语言 结构体的输入输出_C语言的控制结构和输入输出
  10. ROS的学习(十九)用rosserial创建一个subscriber
  11. arduino:废旧光驱DIY激光雕刻机(完善中……)
  12. Jetson-TX2双声卡TLV320AIC32x4 alsa实现同时录音与播放
  13. SpringBoot整合mybatis出现BindingException: Invalid bound statement (not found)问题解决
  14. 干货】最详细、最完美、可以上下左右移动的表格布局,仿同花顺自选列表,老虎证券财报列表,欢迎 Start、Fork
  15. 【快乐离散数学】谓词与量词 | 嵌套量词 | 狄摩根定律 | Predicates and Quantifiers | Nested Quantifiers
  16. 16 《万用之物:盐的故事》-豆瓣评分7.5
  17. cf 487E/uoj 30 Tourists
  18. 2021最新PHP短网址生成系统/短链接生成系统/URL缩短器系统源码
  19. xz2p更新android 9,索尼 XZ2 迎来安卓 9.0 更新,但少了全面屏手势
  20. Lexar雷克沙 nCARD存储卡全网发布,可用于华为手机内存扩容

热门文章

  1. 一步步教你如何用疯狂.NET架构中的通用权限系统 -- 分级管理
  2. [Linux]阿里云免费试用体验(在阿里云的ubuntu上部署个人服务)
  3. 创建分区表+分区表的分类+创建散列分区表+查看散列分区表分区中的数据+创建列表分区表+查看列表分区表分区中的数据...
  4. Spring官网阅读(三)自动注入
  5. 我是如何用 Redis 做实时订阅推送的?
  6. 在 Windows 上直接运行 Linux,有命令行就是贼香
  7. 利用Comet4J 及时推送消息
  8. Java集合:HashMap线程不安全?有哪些表现?
  9. 【阿里云域名】我都有服务器了,为什么还要购买域名?
  10. jQuery面试题-区别mouseover和mouseenter的不同之处(看了也许对你有好处)