- 浏览: 152569 次
- 性别:
- 来自: 上海
文章分类
最新评论
-
北极的。鱼:
几个常用的CSS效果:1.色块透明,文字不透明:设置色块的rg ...
网页前端的浏览器兼容 -
北极的。鱼:
数字证书的作用就是用来说明,里面的公钥是谁的。
数字签名 -
北极的。鱼:
数字证书的作用,其实就是证明,证书里包含的公钥是哪个人的。
数字签名 -
北极的。鱼:
面试题,类似冒泡排序把一个字符串的大写字母放到字符串的后面,各 ...
【转】冒泡排序 -
北极的。鱼:
另一种简单桶排序实现:
using System;
using ...
【转】桶排序(Bucket Sort)
转自:http://www.windbi.com/showtopic-90.aspx
在临时表
create table #T (…)
和表变量
declare @T
table (…)
之间主要有
3
个理论上的不同。
第一个
不同使事务日志不会记录表变量。因此,它们脱离了事务机制的范围,从下面的例子可显而易见:
create table #T (s varchar(128))
declare @T table (s varchar(128))
insert into #T select 'old value #'
insert into @T select 'old value @'
begin transaction
update #T
set s='new value #'
update @T set s='new value @'
rollback
transaction
select * from #T
select * from @T
s
---------------
old value #
s
---------------
new value
@
在声明临时表
#T
和表变量
@T
之后,给它们分配一个相同的值为
old value
字符串。然后,开始一个事务去更新它们。此时,它们都将有新的相同的值
new value
字符串。但当事务回滚时,正如你所看到的,表变量
@T
保留了这个新值而没有返回
old value
字符串。这是因为即使表变量在事务内被更新了,它本身不是事务的一部分。
第二个
主要的不同是任何一个使用临时表的存储过程都不会被预编译,然而使用表变量的存储过程的执行计划可以预先静态的编译。预编译一个脚本的主要好处在于加快了执行的速度。这个好处对于长的存储过程更加显著,因为对它来说重新编译代价太高。
最后
,表变量仅存在于那些变量能存在的相同范围内。和临时表相反,它们在内部存储过程和
exec
(
string
)语句里是不可见的。它们也不能在
insert/exec
语句里使用。
性能比较
首先,准备一个有
100
万记录的测试表:
create table NUM (n int primary key, s
varchar(128))
GO
set nocount on
declare @n int
set @n=1000000
while @n>0 begin
insert into NUM
select @n,'Value:
'+convert(varchar,@n)
set @n=@n-1
end
GO
准备测试存储过程
T1
:
create procedure T1
@total int
as
create table
#T (n int, s varchar(128))
insert into #T select n,s from NUM
where n%100>0 and n<=@total
declare @res varchar(128)
select @res=max(s) from NUM
where n<=@total and
not exists(select * from #T
where #T.n=NUM.n)
GO
使用参数从
10
,
100
,
1000
,
10000
,
100000
到
1000000
不等来调用,它复制给定数量的记录到临时表(一些另外,它跳过那些能被
100
整除的数值),然后找到缺失记录的最大值。当然,记录越多,执行的时间就越长:
为了测量正好的执行时间,使用下面的代码:
declare @t1 datetime, @n int
set
@t1=getdate()
set @n=
100 – (**)
while @n>0 begin
exec T1
1000 – (*)
set @n=@n-1 end
select datediff(ms,@t1,getdate())
GO
(
*
)表示程序里边的参数从
10
到
1000000
不等。
(
**
)表示如果执行时间太短,就重复相同的循环
10
到
100
次不等。
多次运行代码以获得执行的结果。
该结果在下面的表
1
里能找到。
下面试着给临时表添加一个主键来提升存储过程的性能:
create procedure
T2
@total int
as
create table #T (n int
primary key
, s varchar(128))
insert into #T select n,s from NUM
where n%100>0 and n<=@total
declare @res varchar(128)
select @res=max(s) from NUM
where n<=@total and
not exists(select * from #T
where #T.n=NUM.n)
GO
然后,创建第三个。此时有聚集索引,它会工作得更好。但是是在插入数据到临时表之后创建的索引——通常,这样会更好:
create procedure
T3
@total int
as
create table #T (n int, s varchar(128))
insert into #T select n,s from
NUM
where n%100>0 and n<=@total
create clustered index Tind on #T (n)
declare @res varchar(128)
select @res=max(s) from NUM
where n<=@total and
not exists(select * from
#T
where #T.n=NUM.n)
GO
令人惊奇!大数据量花费的时间很长;仅仅添加
10
条记录就花费了
13
毫秒。这个问题在于创建索引语句强迫
SQLServer
去重新编译存储过程,显著的降低了执行效率。
现在试着使用表变量来完成相同的事情:
create procedure
V1
@total int
as
declare @V table (n int, s
varchar(128))
insert into
@V
select n,s from NUM
where n%100>0 and n<=@total
declare @res varchar(128)
select @res=max(s) from NUM
where n<=@total and
not exists(select * from
@V V
where V.n=NUM.n)
GO
使我们惊奇的是,该版本不是明显的比用临时表的快。这是由于在存储过程开头创建表
#T
语句时进行了特别优化的缘故。对整个范围内的值,
V1
和
T1
工作得一样好。
下面试试有主键的情形:
create procedure
V2
@total int
as
declare @V table (n int
primary key
, s varchar(128))
insert into @V select n,s from NUM
where n%100>0 and n<=@total
declare @res varchar(128)
select @res=max(s) from NUM
where n<=@total and
not exists(select * from @V V
where V.n=NUM.n)
GO
这个结果很快,但
T2
超过了该版本。
Records |
T1 |
T2 |
T3 |
V1 |
V2 |
10 |
0.7 |
1 |
13.5 |
0.6 |
0.8 |
100 |
1.2 |
1.7 |
14.2 |
1.2 |
1.3 |
1000 |
7.1 |
5.5 |
27 |
7 |
5.3 |
10000 |
72 |
57 |
82 |
71 |
48 |
100000 |
883 |
480 |
580 |
840 |
510 |
1000000 |
45056 |
6090 |
15220 |
20240 |
12010 |
表
1
:使用
SQLServer2000
,时间单位毫秒
但真正使我们震惊的是在
SQLServer2005
上的情形:
N |
T1 |
T2 |
T3 |
V1 |
V2 |
10 |
0.5 |
0.5 |
5.3 |
0.2 |
0.2 |
100 |
2 |
1.2 |
6.4 |
61.8 |
2.5 |
1000 |
9.3 |
8.5 |
13.5 |
168 |
140 |
10000 |
67.4 |
79.2 |
71.3 |
17133 |
13910 |
100000 |
700 |
794 |
659 |
Too long!
|
Too long!
|
1000000 |
10556 |
8673 |
6440 |
Too long!
|
Too long!
|
表
2
:使用
SQLServer2005
(时间单位毫秒)
有时,
SQL2005
比
SQL2000
快(上面标记为绿色的部分)。但大多数情况下,特别是在数据量巨大时,存储过程使用表变量花费了更长的时间(红色部分)。在
4
种情形下,我甚至放弃了等待。
结论
- 在什么时候和什么地方使用临时表或表变量没有一个普遍的规则。试着都测试测试它们。
- 在你的测试里,少量的记录和大量的数据集都要进行测试。
- 当在你的存储过程里使用了复杂的逻辑的时候要小心迁移到 SQL2005 。相同的代码在 SQLServer2005 上可能运行要慢 10 到 100 倍。
发表评论
-
【转】分页存储过程
2016-08-16 10:50 376ALTER PROCEDURE [dbo].[Sp_Pag ... -
【转】游标
2015-03-24 22:25 625转自:http://www.cnblogs.com/hooj ... -
【转】事务
2015-03-24 22:24 734转自:http://www.cnblogs.com/hoo ... -
【转】存储过程
2015-03-24 21:31 525转自:http://www.cnblogs.com/hooj ... -
【转】数据库trigger
2015-03-24 18:55 500转自:http://www.cnblogs.com/hooj ... -
【转】数据库trigger
2015-03-24 18:54 417转自:http://www.cnblogs.com/hooj ... -
SQL Server游标的使用【转】
2014-11-12 16:56 573转自:http://www.cnblogs.c ... -
【转】SQL Server索引优化方案
2011-08-10 09:48 1544转自:http://blog.csdn.net/ylqmf/a ... -
【转】SQL Server创建索引
2011-08-09 09:38 1125转自:http://blog.csdn.net/lenotan ... -
【转】聚集索引和非聚集索引(整理)
2011-07-22 16:04 754转自:http://www.cnblogs.com/aspne ... -
Sql中判断“数据库"、"表"、"临时表"、"存储过程"和列”是否存在
2010-12-16 11:22 1296--判断数据库是否存在 IF EXISTS (SELECT * ... -
【转】返回架构范围内对象的数据库对象标识号——OBJECT_ID (Transact-SQL)
2010-12-16 11:16 808【转自 MSDN : http://msdn.microsof ... -
【转】SQL Server 2000 中 master 数据库内的系统表映射到它们在 SQL Server 2008 中对应的系统视图或函数
2010-12-16 10:50 1412【转自MSDN : http://msdn.micros ... -
【转】详解SQL Server中的临时表和表变量
2010-12-16 10:35 1083在SQL Server的性能调优中,有一个不可比拟的问题: ... -
sql case when 语法
2010-12-16 10:32 2611select 姓名,工龄, (case when (工 ... -
sql临时表创建后要手动删除的么!
2010-12-16 10:29 1733临时表分两种 一是普通临时表 create table # ...
相关推荐
资源名称:SQLServer中临时表与表变量的区别内容简介: 本文档主要讲述的是SQLServer中临时表与表变量的区别;希望本文档会给有需要的朋友带来帮助;感兴趣的朋友可以过来看看。资源截图: 资源太大,传百度网盘了,...
sqlserver 循环临时表插入数据到另一张表 -- 声明变量 DECLARE @SupCode as varchar(100), @ProdCode as varchar(50), @PackLayer as varchar(50), @CodeStatus as varchar(50), @ProductId as varchar(50), @...
我们在数据库中使用表的时候,经常会遇到两种使用表的方法,分别就是使用临时表及表变量。
表变量在SQL Server 2000中首次被引入。表变量的具体定义包括列定义,列名,数据类型和约束。而在表变量中可以使用的约束包括主键约束,唯一约束,NULL约束和CHECK约束(外键约束不能在表变量中使用)。定义表变量的...
该书由Itzik Ben-Gan权威执笔,重点关注语言特性以及它们如何被SQL Server引擎解释和处理。 通过本书,你将深入了解T-SQL的高级用法,包括触发器、用户自定义函数、异常处理等。该书解释并比较了SQL Server 2000和...
说临时表和表变量,这是一个古老的话题,我们在网上也找到很多的资料阐述两者的特征,优点与缺点
书中全面深入地介绍了T-SQL的基本元素,以及SQL Server 2008中新增加的一些特性。主要包括SQL的基础理论、逻辑查询处理、SELECT查询、连接和子查询、表表达式、过滤和分组、透视转换、修改数据、事务和一致性的处理...
考虑使用表变量而不使用临时表。当需要在临时表上显式地创建索引时,或多个存储过程或函数需要使用表值时,临时表很有用。通常,表变量提供更有效的查询处理。
SQL Server 文档小组无法回答技术支持问题,但是欢迎您对本自述文档提出建议和意见。您可以使用提供的链接快速、直接地发送电子邮件反馈。请使用英语发送您的反馈信息。 若要通过邮件提交有关本文档的反馈信息,请...
锁和死锁对系统性能的各种影响 理解触发器及其使用方式 《SQL Server 2008编程入门经典(第3版)》读者对象 《SQL Server 2008编程入门经典(第3版)》适合于希望全面了解数据库设计概念和学习SQL的开发人员。读者具有...
21天学习SQL V1.0.pdf 66 SQL 21 日自学通(V1.0) 翻译人笨猪 EMAIL wyhsillypig@163.com 2 日期/时间函数.........................................................................................................
SQL Server 向临时表插入数据,用临时表和表变量代替游标会极大的提高性能,下面有个示例,大家可以参考下
第1章 RDBMS基础:SQLServer数据库的构成 1.1 数据库对象概述 1.1.1 数据库对象 1.1.2 事务日志 1.1.3 最基本的数据库对象:表 1.1.4 文件组 1.1.5 数据库关系图 1.1.6 视图 1.1.7 存储过程 1.1.8 用户自定义函数 ...
锁和死锁对系统性能的各种影响 理解触发器及其使用方式 《SQL Server 2008编程入门经典(第3版)》读者对象 《SQL Server 2008编程入门经典(第3版)》适合于希望全面了解数据库设计概念和学习SQL的开发人员。读者具有...
SQL Server数据库技术大全 电子书 图书目录: 第1篇 SQL Server基础 第1章 SQL Server 2008概述/2 1.1 SQL Server 2008简介/2 1.1.1 SQL Server发展历史/2 1.1.2 SQL Server 2008的特点/4 1.2 SQL Server 2008架构...
最近在利用 SSRS 2005 做报表的时候,调用带有临时表的...使用一个不包含临时表的SQL语句创建报表,创建成功以后,修改数据源,替换上包含临时表的SQL命令或者存储过程,这时用SSRS 2005自带的语法检查功能对数据源语
创建临时表 .......... 25 sybsecurity 数据库 .......... 25 sybsystemdb 数据库 .......... 26 sybmgmtdb 数据库 .......... 26 pubs2 和 pubs3 样本数据库 .......... 26 维护样本数据库 .......... 27 pubs2 ...
书中全面深入地介绍了T-SQL的基本元素,以及SQL Server 2008中新增加的一些特性。主要包括SQL的基础理论、逻辑查询处理、SELECT查询、连接和子查询、表表达式、过滤和分组、透视转换、修改数据、事务和一致性的处理...