原文:如何track存储过程的编译次数

转载自此处

有个script我们很熟悉,是用来去查找当前SQL
Server中哪些存储过程变重编译的次数最多的:

--Gives you the top 25 stored procedures that have been recompiled.

select top 25 sql_text.text, sql_handle, plan_generation_num,  execution_count,

dbid,  objectid

into DMV_Top25_Recompile_Commands

from sys.dm_exec_query_stats a

cross apply sys.dm_exec_sql_text(sql_handle) as sql_text

where plan_generation_num >1

order by plan_generation_num desc

go

那么,这个脚本究竟是记录什么情况下的存储过程recomile呢?

我们在SQL Server上创建一个这样的store
procedure:

create proc aaa

as

select plan_generation_num,* FROM DMV_Top25_Recompile_Commands where plan_generation_num  > 2

然后准备好用这个脚本来返回plan_generation_num的值

select top 25 sql_text.text, sql_handle, plan_generation_num,  execution_count,

dbid,  objectid

from sys.dm_exec_query_stats a

cross apply sys.dm_exec_sql_text(sql_handle) as sql_text

where  sql_text.text like '%aaa%'

order by plan_generation_num desc

Exec aaa之后的脚本返回结果:

这里的第六行结果集就是我们的存储过程aaa。这时的plan_generation_num值显示为1.

接下来我们mark recompile:

sp_recompile aaa

然后再次执行 exec aaa

使用脚本查询:

这里看到存储过程重编译以后,plan_generation_num的值并没有增加。

那为什么我们还会使用这样的脚本来返回重编译次数很多的存储过程呢?

接下来我们再次将存储过程mark recompile,然后直接使用脚本查询:

这时,我们发现该存储过程的plan 和text已经从DMV中移除了。看起来sp_recompile会直接将cache中缓存的执行计划和语句直接标识成不可用。因此DMV中就没有相关的记录了。

这就是说,存储过程标识重编译这种模式导致的重编译,从DMV里面是没有办法跟踪的。

那么从性能监视器的计数器 “sp
recompilation/sec”里面能不能跟踪到呢?

我们反复执行:

sp_recompile aaa

exec aaa

性能监视器中一直显示为0

那么plan_generation_num的值究竟是什么含义呢?BOL中的解释很简单:

A sequence number that can be used to distinguish between instances of plans after a recompile.

中文版的含义为:可用于在重新编译后区分不同计划实例的序列号。

这里并没有说明如何去计算的序列号。我们从另一篇英文的blog中找到了更加详细的说明:

There are a lot of interesting columns in P and S, especially in S, and here I will only discuss what I have learned about plan_generation_num in S. SQL Server 2005 treats the compiled plan for a stored
procedure as an array of subplans, one for each query statement. If an individual subplan needs recompilation, it does so without causing the whole plan to recompile. In doing so, SQL Server increments the plan_generation_num on the subplan record to be 1
+ MAX(plan_generation_num for all subplans). The general distribution of plan_generation_num among all subplans for a given plan is such that it has multiple of 1's and distinct numbers > 1. That is because all subplans start with 1 as their plan_generation_num.
Appendix A is the query for learning plan_generation_num.

http://lfsean.blogspot.com/2008/02/understanding-sql-plangenerationnum.html

这部分说明简单的来说,就是只要存储过程中有一条语句发生重编译,这个plan_generation_num值就会+1.这里并没有说是整个存储过程重编译的时候,这个值会+1.

接下来我们修改测试存储过程aaa:

Alter TABLE aaa_table(

[text] [nvarchar](max) NULL,

[sql_handle] [varbinary](64) NOT NULL,

[plan_generation_num] [bigint] NOT NULL,

[execution_count] [bigint] NOT NULL,

[dbid] [smallint] NULL,

[objectid] [int] NULL

) ON [PRIMARY]

insert into aaa_table select * from DMV_Top25_Recompile_Commands where 1=2

insert into aaa_table select * from DMV_Top25_Recompile_Commands where 1=2

insert into aaa_table select * from DMV_Top25_Recompile_Commands where 1=2

insert into aaa_table select * from DMV_Top25_Recompile_Commands where 1=2

insert into aaa_table select * from DMV_Top25_Recompile_Commands where 1=2

然后我们执行存储过程,收集profiler trace,同时继续监控性能监视器

开始重新执行存储过程aaa

这里我们可以看到sp recompilation/sec立刻变成了7。

Profiler trace中可以看到每条insert语句上都触发了一个sp:recompile

脚本的查询结果:

可以看到plan_generation_num的值增加到6了。

为什么这样写存储过程会导致重编译?http://support.microsoft.com/kb/243586 这篇文章中列举了多种会导致存储过程重编译的情况:

aaa这个存储过程符合这个条件:

The procedure interleaves Data Definition Language (DDL) and Data Manipulation Language (DML) operations.

因此我们的结论是,使用这个脚本去查询重编译次数高的存储过程是没有错的,但是这个脚本并不包含由于sp_recompile已经定义存储过程时使用了with
recompile的选项而导致的存储过程重编译的情况。

如何track存储过程的编译次数的更多相关文章

  1. SQL SERVER 临时表导致存储过程重编译(recompile)的一些探讨

    SQLSERVER为了确保返回正确的值,或者处于性能上的顾虑,有意不重用缓存在内存里的执行计划,而重新编译执行计划的这种行为,被称为重编译(recompile).那么引发存储过程重编译的条件有哪一些呢 ...

  2. sqlserver 存储过程中使用临时表到底会不会导致重编译

    曾经在网络上看到过一种说法,SqlServer的存储过程中使用临时表,会导致重编译,以至于执行计划无法重用, 运行时候会导致重编译的这么一个说法,自己私底下去做测试的时候,根据profile的跟踪结果 ...

  3. SQL Server 查看存储过程执行次数的方法

    今天老大提出一个需求,想查看数据库存储过程执行的次数,以前没有接触过,于是网上找了下,发现还真有! 不废话,贴出来sql语句,直接执行即可看到结果: use master select text,ex ...

  4. 关于T-SQL重编译那点事,WITH RECOMPILE和OPTION(RECOMPILE)区别仅仅是存储过程级重编译和SQL语句级重编译吗

    本文出处:http://www.cnblogs.com/wy123/p/6262800.html   在考虑重编译T-SQL(或者存储过程)的时候,有两种方式可以实现强制重编译(前提是忽略导致重编译的 ...

  5. 理解性能的奥秘——应用程序中慢,SSMS中快(2)——SQL Server如何编译存储过程

    本文属于<理解性能的奥秘--应用程序中慢,SSMS中快>系列 接上文:理解性能的奥秘--应用程序中慢,SSMS中快(1)--简介 本文介绍SQL Server如何编译存储过程并使用计划缓存 ...

  6. WITH RECOMPILE和OPTION(RECOMPILE)区别仅仅是存储过程级重编译和SQL语句级重编译吗

    在考虑重编译T-SQL(或者存储过程)的时候,有两种方式可以实现强制重编译(前提是忽略导致重编译的其他因素的情况下,比如重建索引,更新统计信息等等), 一是基于WITH RECOMPILE的存储过程级 ...

  7. Oracle-检查原因并重新编译无效的存储过程

    1.查看存储过程编译无效的原因 show errors procedure hr.getperson; 2.指定一个存储过程进行编译 alter procedure  hr.getperson com ...

  8. oracle 存储过程 包 【转】

    一.为什么要用存储过程? 如果在应用程序中经常需要执行特定的操作,可以基于这些操作简历一个特定的过程.通过使用过程可以简化客户端程序的开发和维护,而且还能提高客户端程序的运行性能. 二.过程的优点? ...

  9. 小白学习mysql之存储过程的优劣分析以及接入控制

    存储过程的优劣 存储过程是一组实现特定功能的SQL语句集合,存储过程一经编译便存储在了服务器上,可以通过调用存储过程的名字以及传入相应的参数来使用存储过程.要高层次的掌握存储过程,不能觉得依葫芦画瓢, ...

随机推荐

  1. 站点接入QQ登录

    首先引入授权js文件 <script type="text/javascript" src="http://qzonestyle.gtimg.cn/qzone/op ...

  2. OCP读书笔记(17) - 计划任务

    轻量级作业: 也称为持久性轻量级作业,如果当我们的数据库每秒钟需要创建.删除或修改数十个或数百个作业时,使用轻量级作业是降低开销的最佳方法 常规作业:是由oracle 11g Scheduler 所支 ...

  3. win7问题解决,凭据管理器和无法访问,不允许一个用户使用一个以上用户名与服务器或共享资源进行多重连接。

    WIN7凭据管理器,如果你用一个帐号远程登录以后在电脑中会记住这个信息,假如你想用另外的帐号,那么就到控制面板-凭据管理器里中进行修改或者删除. 如果你登录以后提示,“无法访问.不允许一个用户使用一个 ...

  4. matlab 2014a 改为英文版本号

    1. 在 Matlab 的安装目录以下找到例如以下的路径,X:\MATLAB\R2014a\java\jar,当中 X 为安装盘符,这个不用过多解释了,然后找到目录 zh_CN.此目录就是中文界面的语 ...

  5. 源代码编译安装 PHP5.5.0,解决curl_exec訪问HTTPS返回502错误的问题

    近期碰到一个奇怪的问题. PHP使用 curl_exec 訪问 HTTPS 网页时, 返回502错误, 訪问HTTP网页时没有问题,  用   echo   phpinfo() ;  查看. 支持op ...

  6. hdu 5017 Ellipsoid(西安网络赛 1011)

    Ellipsoid Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total ...

  7. Xamarin.Android中使用android:onClick="xxx"属性

    原文:Xamarin.Android中使用android:onClick="xxx"属性 在原生Android开发中,为一个View增加点击事件,有三种方式: 1.使用匿名对象 ( ...

  8. 黄聪:Microsoft Enterprise Library 5.0 系列教程(八) Unity Dependency Injection and Interception

    原文:黄聪:Microsoft Enterprise Library 5.0 系列教程(八) Unity Dependency Injection and Interception 依赖注入容器Uni ...

  9. 设计模式C++达到 3.抽象工厂

    简单工厂模式和工厂模式 要求 同类型的产品子类有共同的方法.这限制了产品子类的扩展.抽象工厂能client它提供了一个接口,它是client而不必指定产品的详细信息.创建多个产品系列产品对象.在归为一 ...

  10. 【Android开发经验】Android举UI设计经验

    转载请注明出处:http://blog.csdn.net/zhaokaiqiang1992 1.Android眼下的主流设备分辨率为480×800.720×1280.1080×1920,单位是像素.在 ...