原文:如何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. Service组件 总结 + 绑定理Service三种实现方式 Messager + Binder + AIDL

    在Android中进程按优先级可以分为五类,优先级从高到低排列: - 前台进程 该进程包含正在与用户进行交互的界面组件,比如一个Activity - 可视进程 该进程中的组件虽然没有和用户交互,但是仍 ...

  2. 策略模式——MFC样例

    Context(应用场景): 1.须要使用ConcreteStrategy提供的算法. 2.内部维护一个Strategy的实例. 3. 负责动态设置执行时Strategy详细的实现算法. 4.负责跟S ...

  3. Linux系统部署规范v1.0

    Linux系统部署规范v1.0 目的: 1.尽可能减少线上操作: 2.尽可能实现自动化部署: 3.尽可能减少安装服务和启动的服务: 4.尽可能使用安全协议提供服务: 5.尽可能让业务系统单一: 6.尽 ...

  4. (hdu step 7.1.3)Lifting the Stone(求凸多边形的重心)

    题目: Lifting the Stone Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Other ...

  5. 将Excel数据表到数据库表

    假设你有大量的数据要导入到数据库表,恐怕是没有效率的写程序,作为用于数据操纵,Excel在这方面有优势,但是,如何将其结合起来?将Excel数据表到数据库表,就是本篇博客的目的. 首先去下载MySQL ...

  6. Emacs经常使用快捷键的注意事项

    一直用VIM,尝试了好几次Emacs都被它"多得像天上的星星"一样的快捷键给吓倒了.这几天最终下定决心再次尝试. 将它的Tutor练习了一下,顺便对经常使用快捷键做了一下笔记,方便 ...

  7. Chrome应用技巧之代码整理。

    我们有时候在看别人站点代码时往往是经过压缩的,代码都在一行上了,调试非常是困难,今天给大家介绍一种基本Chrome浏览器的代码整理方法.请看图:

  8. JavaScript语言基础知识10

    JavaScript中间if声明: <span style="font-size:18px;"><HTML> <HEAD> <TITLE& ...

  9. IAR FOR ARM 各版本号,须要的大家能够收藏了

    首先感谢大家的支持与关注,如今应该又一次编辑这篇文章了,这篇文章是非常久曾经不知在什么地方Copy过来的, 非常多问题不知怎么解决,如今我用的是KEIL for arm. 用过Keil和IAR,个人感 ...

  10. jQuery来源学习笔记:扩展的实用功能

    // 扩展的实用功能 jQuery.extend({ // http://www.w3school.com.cn/jquery/core_noconflict.asp // 释放$的 jQuery 控 ...