欢迎来到.net学习网

欢迎联系站长一起更新本网站!QQ:879621940

您当前所在位置:首页 » SQLServer教程 » 正文

CTE,临时表,表变量区别跟具体适用场景分析问题(二)

创建时间:2013年12月20日 15:12  阅读次数:(7469)
分享到:
接上文"CTE,临时表,表变量区别跟具体适用场景分析",我们再看一个问题:
----------------------------------------------------------------------------------------
问题
----------------------------------------------------------------------------------------
例子1:
create procedure Proc1
as 
begin
create table #t1(a int, b int); 
insert into #t1 values(1,2);
select * from #t1;
end

exec Proc1
go 
exec Proc1
GO

例子2
create procedure Proc1
as 
begin
create table #t1(a int, b int); 
insert into #t1 values(1,2);
exec Proc2; 
end
go
create procedure Proc2
as
begin
select * from #t1;
end
go
exec Proc1
go
exec Proc1
go

我们可以看到,上面的2个例子,SP1跟SP2,
在SP1中第二次执行exec Proc1的时候,不会引起重编译,
但是在SP2中第二次执行exec Proc1的时候,却会引起重编译,为什么呢?

----------------------------------------------------------------------------------------
答案
----------------------------------------------------------------------------------------
1.第一个case,我很久以前经常用表变量去inner join其它的表,当发现表变量数据稍多,整个语句就会变的很差,之后就一直按“数据很少就用表变量,数据多点就用临时表。”刚看到这个贴子,就想了想查了查,主要原因还是表变量的行数未知,SQL优化器必须估一个值,这个值往往是很小,在这种情况下去inner join其它表,基本上都会是Nested loop join,此时一旦表变量数据量大,性能将会变得极差。而这种情况下我们往往需要merge join 或 hash join才更有效率,recompile选项能让优化器去更新表变量的统计信息,而这样就能根据统计信息生成合理的执行计划。

2.至于第二个关于存储过程的case,两个场景主要关键点还是第二个proc2中引用非自己创建的临时表,这个引用是依靠临时表ID,当执行proc1生成临时表时,名字(执行计划依靠名字)不变但id会变,而proc2依靠这个id,这相当于proc2要查的临时表架构发生变化,所以每次都要重编译,如果在proc1里同时有两个exec proc2,那么第二个不会重编译,因为此时它可以重新第一个exec proc2的执行计划了,因为两个exec proc2引用的临时表是同名同ID。Hr,gsS颯銐砆顣槝0s
来源:http://bbs.csdn.net/topics/390667246
说明:所有来源为 .net学习网的文章均为原创,如有转载,请在转载处标注本页地址,谢谢!
【编辑:Wyf

打赏

取消

感谢您的支持,我会做的更好!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

最新评论

共有评论0条
  • 暂无任何评论,请留下您对本文章的看法,共同参入讨论!
发表评论:
留言人:
内  容:
请输入问题 32+44=? 的结果(结果是:76)
结  果: