热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

数据库技术:SQLServer如何查看存储过程的执行计划

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

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

 

 

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如何查看存储过程的执行计划,都可以关注数据库技术分享栏目—编程笔记


推荐阅读
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • 本文详细介绍了SQL日志收缩的方法,包括截断日志和删除不需要的旧日志记录。通过备份日志和使用DBCC SHRINKFILE命令可以实现日志的收缩。同时,还介绍了截断日志的原理和注意事项,包括不能截断事务日志的活动部分和MinLSN的确定方法。通过本文的方法,可以有效减小逻辑日志的大小,提高数据库的性能。 ... [详细]
  • 本文由编程笔记小编整理,介绍了PHP中的MySQL函数库及其常用函数,包括mysql_connect、mysql_error、mysql_select_db、mysql_query、mysql_affected_row、mysql_close等。希望对读者有一定的参考价值。 ... [详细]
  • 如何实现织梦DedeCms全站伪静态
    本文介绍了如何通过修改织梦DedeCms源代码来实现全站伪静态,以提高管理和SEO效果。全站伪静态可以避免重复URL的问题,同时通过使用mod_rewrite伪静态模块和.htaccess正则表达式,可以更好地适应搜索引擎的需求。文章还提到了一些相关的技术和工具,如Ubuntu、qt编程、tomcat端口、爬虫、php request根目录等。 ... [详细]
  • 一、Hadoop来历Hadoop的思想来源于Google在做搜索引擎的时候出现一个很大的问题就是这么多网页我如何才能以最快的速度来搜索到,由于这个问题Google发明 ... [详细]
  • 本文介绍了lua语言中闭包的特性及其在模式匹配、日期处理、编译和模块化等方面的应用。lua中的闭包是严格遵循词法定界的第一类值,函数可以作为变量自由传递,也可以作为参数传递给其他函数。这些特性使得lua语言具有极大的灵活性,为程序开发带来了便利。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • 本文介绍了如何使用Power Design(PD)和SQL Server进行数据库反向工程的方法。通过创建数据源、选择要反向工程的数据表,PD可以生成物理模型,进而生成所需的概念模型。该方法适用于SQL Server数据库,对于其他数据库是否适用尚不确定。详细步骤和操作说明可参考本文内容。 ... [详细]
  • 本文介绍了使用Java实现大数乘法的分治算法,包括输入数据的处理、普通大数乘法的结果和Karatsuba大数乘法的结果。通过改变long类型可以适应不同范围的大数乘法计算。 ... [详细]
  • PHP设置MySQL字符集的方法及使用mysqli_set_charset函数
    本文介绍了PHP设置MySQL字符集的方法,详细介绍了使用mysqli_set_charset函数来规定与数据库服务器进行数据传送时要使用的字符集。通过示例代码演示了如何设置默认客户端字符集。 ... [详细]
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • 本文详细介绍了MysqlDump和mysqldump进行全库备份的相关知识,包括备份命令的使用方法、my.cnf配置文件的设置、binlog日志的位置指定、增量恢复的方式以及适用于innodb引擎和myisam引擎的备份方法。对于需要进行数据库备份的用户来说,本文提供了一些有价值的参考内容。 ... [详细]
  • 使用Ubuntu中的Python获取浏览器历史记录原文: ... [详细]
  • 本文介绍了Oracle数据库中tnsnames.ora文件的作用和配置方法。tnsnames.ora文件在数据库启动过程中会被读取,用于解析LOCAL_LISTENER,并且与侦听无关。文章还提供了配置LOCAL_LISTENER和1522端口的示例,并展示了listener.ora文件的内容。 ... [详细]
  • 本文介绍了Hyperledger Fabric外部链码构建与运行的相关知识,包括在Hyperledger Fabric 2.0版本之前链码构建和运行的困难性,外部构建模式的实现原理以及外部构建和运行API的使用方法。通过本文的介绍,读者可以了解到如何利用外部构建和运行的方式来实现链码的构建和运行,并且不再受限于特定的语言和部署环境。 ... [详细]
author-avatar
1257523034_627418
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有