MSSQL存储过程中使用临时表到底会不会导致重编译
Tags: MSSQLSQL Server临时表重编译
曾经在网络上看到过一种说法,SqlServer的存储过程中使用临时表,会导致重编译,以至于执行计划无法重用,
运行时候会导致重编译的这么一个说法,自己私底下去做测试的时候,根据profile的跟踪结果,
存储过程中使用临时表,如果不是统计信息变更导致导致的重编译,并不会导致重编译,
但是现实情况下,对于一些特殊的情况,即便是统计信息没有更新,又确实会出现每次运行都重编译的情况,
存储过程中使用了临时表,什么情况下会重编译,什么情况下不用重编译?
为了弄清楚这个问题,查阅了大量的资料,才把这个问题弄清楚,这里特意记录下来,
希望武断地认为存储过程中使用了临时表就会导致重编译的这个观点得到纠正。
首先进行下面的测试,我们知道,导致临时表重编译的因素之一就是统计信息的变化,统计信息的变化依赖于往临时表中写入的数据量,
首选我要控制插入临时表中的数据量不超过统计信息更新而导致重编译的阀值,先排除统计信息的变更导致重编译,
看看仅仅是多次运行SP,是否因为存储过程中有了临时表而会产生重编译
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | --首选创建一个表,供存储过程中测试使用 create table test1 ( id int identity(1,1), name varchar(50) ) --插入10000条测试数据 insert into test1 values (NEWID()) go 10000 --创建一个存储过程,其中存储过程中定义了一个临时表,根据参数,往临时表中写入数据 create proc testRecompile(@i int) as begin create table #t (id int,name varchar(50)) insert into #t select id,name from test1 where id<@i select * from #t end |
那么就开始运行这个SP,然后监控profile,看看第一次运行,以及除了第一次运行之后,到底有没有发生重编译
1 2 3 4 | --第一次运行,代入参数1 exec testRecompile 1 --第二次运行,代入参数2 exec testRecompile 2 |
下面是profile的截图,可以很清楚地看到,第一次运行之后,再次运行SP的时候,没有发生重编译的动作,也就是说重用了第一次的执行计划缓存