- 浏览: 1001418 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (529)
- 服务器 (8)
- jsp (1)
- java (6)
- AIX (1)
- solaris (3)
- linux学习 (53)
- javaScript (2)
- hibernate (1)
- 数据库 (74)
- sql语句 (8)
- oracle 学习 (75)
- oracle 案例 (42)
- oracle 管理 (42)
- Oracle RAC (27)
- oracle data guard (12)
- oracle 参数讲解 (14)
- Oracle 字符集 (8)
- oracle性能调优 (24)
- oracle备份与恢复 (12)
- oracle Tablespace (9)
- oracle性能诊断艺术 (1)
- oracle 11g学习 (5)
- oracle streams (1)
- oracle upgrade and downgrade (4)
- db2学习 (13)
- db2命令学习 (2)
- mysql (28)
- sql server (30)
- sql server 2008 (0)
- 工具 (10)
- 操作系统 (3)
- c++ (1)
- stock (1)
- 生活 (5)
- HADOOP (2)
最新评论
-
massjcy:
...
如何将ubuntu文件夹中文名改为英文 -
skypiea:
谢谢。。。
终于解决了。。。
Oracle 10.2.0.4(5)EM不能启动的解决方案(Patch 8350262) -
qwe_rt:
引用vi /etc/sysconfig/network 请问 ...
Linux操作系统下配置静态IP上网 -
liuqiang:
sudo killall -9 apache2
ps 和 kill 命令详解 -
dazuiba:
引用*绝杀 kill -9 PID 当使用此命令时,一定要通过 ...
ps 和 kill 命令详解
我们在数据库中使用表的时候,经常会遇到两种使用表的方法,分别就是使用临时表及表变量。在实际使用的时候,我们如何灵活的在存储过程中运用它们,虽然它们实现的功能基本上是一样的,可如何在一个存储过程中有时候去使用临时表而不使用表变量,有时候去使用表变量而不使用临时表呢?
临时表
临时表与永久表相似,只是它的创建是在Tempdb中,它只有在一个数据库连接结束后或者由SQL命令DROP掉,才会消失,否则就会一直存在。临时表在创建的时候都会产生SQL Server的系统日志,虽它们在Tempdb中体现,是分配在内存中的,它们也支持物理的磁盘,但用户在指定的磁盘里看不到文件。
临时表分为本地和全局两种,本地临时表的名称都是以“#”为前缀,只有在本地当前的用户连接中才是可见的,当用户从实例断开连接时被删除。全局临时表的名称都是以“##”为前缀,创建后对任何用户都是可见的,当所有引用该表的用户断开连接时被删除。
下面我们来看一个创建临时表的例子:
CREATE TABLE dbo.#News ( News_id int NOT NULL, NewsTitle varchar(100), NewsContent varchar(2000), NewsDateTime datetime )
临时表可以创建索引,也可以定义统计数据,所以可以用数据定义语言(DDL)的声明来阻止临时表添加的限制,约束,并参照完整性,如主键和外键约束。比如来说,我们现在来为#News表字段NewsDateTime来添加一个默认的GetData()当前日期值,并且为News_id添加一个主键,我们就可以使用下面的语句:
ALTER TABLE dbo.#News ADD CONSTRAINT [DF_NewsDateTime] DEFAULT (GETDATE()) FOR [NewsDateTime], PRIMARY KEY CLUSTERED ( [News_id] ) ON [PRIMARY] GO
临时表在创建之后可以修改许多已定义的选项,包括:
1)添加、修改、删除列。例如,列的名称、长度、数据类型、精度、小数位数以及为空性均可进行修改,只是有一些限制而已。
2)可添加或删除主键和外键约束。
3)可添加或删除 UNIQUE 和 CHECK 约束及 DEFAULT 定义(对象)。
4)可使用 IDENTITY 或 ROWGUIDCOL 属性添加或删除标识符列。虽然 ROWGUIDCOL 属性也可添加至现有列或从现有列删除,但是任何时候在表中只能有一列可具有该属性
5)表及表中所选定的列已注册为全文索引。
表变量
表变量创建的语法类似于临时表,区别就在于创建的时候,必须要为之命名。表变量是变量的一种,表变量也分为本地及全局的两种,本地表变量的名称都是以“@”为前缀,只有在本地当前的用户连接中才可以访问。全局的表变量的名称都是以“@@”为前缀,一般都是系统的全局变量,像我们常用到的,如@@Error代表错误的号,@@RowCount代表影响的行数。
如我们看看创建表变量的语句:
DECLARE @News Table ( News_id int NOT NULL, NewsTitle varchar(100), NewsContent varchar(2000), NewsDateTime datetime )
比较临时表及表变量都可以通过SQL的选择、插入、更新及删除语句,它们的的不同主要体现在以下这些:
1)表变量是存储在内存中的,当用户在访问表变量的时候,SQL Server是不产生日志的,而在临时表中是产生日志的;
2)在表变量中,是不允许有非聚集索引的;
3)表变量是不允许有DEFAULT默认值,也不允许有约束;
4)临时表上的统计信息是健全而可靠的,但是表变量上的统计信息是不可靠的;
5)临时表中是有锁的机制,而表变量中就没有锁的机制。
我们现在来看一个完整的例子,来看它们的用法的异同:
利用临时表
CREATE TABLE dbo.#News ( News_id int NOT NULL, NewsTitle varchar(100), NewsContent varchar(2000), NewsDateTime datetime ) INSERT INTO dbo.#News (News_id, NewsTitle, NewsContent, NewsDateTime) VALUES (1,'BlueGreen', 'Austen', 200801, GETDATE()) SELECT News_id, NewsTitle, NewsContent, NewsDateTime FROM dbo.#News DROP TABLE dbo.[#News]
利用表变量
DECLARE @News table ( News_id int NOT NULL, NewsTitle varchar(100), NewsContent varchar(2000), NewsDateTime datetime ) INSERT INTO @News (News_id, NewsTitle, NewsContent, NewsDateTime) VALUES (1,'BlueGreen', 'Austen', 200801, GETDATE()) SELECT News_id, NewsTitle, NewsContent, NewsDateTime FROM @News
我们可以看到上面两种情况实现的是一样的效果,第一种利用临时表的时候,临时表一般被创建后,如果在执行的时候,没有通过DROP Table的操作,第二次就不能再被创建,而定义表变量也不需要进行DROP Table的操作,一次执行完成后就会消失。
其实在选择临时表还是表变量的时候,我们大多数情况下在使用的时候都是可以的,但一般我们需要遵循下面这个情况,选择对应的方式:
1)使用表变量主要需要考虑的就是应用程序对内存的压力,如果代码的运行实例很多,就要特别注意内存变量对内存的消耗。我们对于较小的数据或者是通过计算出来的推荐使用表变量。如果数据的结果比较大,在代码中用于临时计算,在选取的时候没有什么分组的聚合,就可以考虑使用表变量。
2)一般对于大的数据结果,或者因为统计出来的数据为了便于更好的优化,我们就推荐使用临时表,同时还可以创建索引,由于临时表是存放在Tempdb中,一般默认分配的空间很少,需要对tempdb进行调优,增大其存储的空间。
补充:
1.使事务日志不会记录表变量。因此,它们脱离了事务机制的范围。
2.任何一个使用临时表的存储过程都不会被预编译,然而使用表变量的存储过程的执行计划可以预先静态的编译。预编译一个脚本的主要好处在于加快了执行的速度。这个好处对于长的存储过程更加显著,因为对它来说重新编译代价太高。
3.表变量仅存在于那些变量能存在的相同范围内。和临时表相反,它们在内部存储过程和exec(string)语句里是不可见的。它们也不能在insert/exec语句里使用。
问题 1:为什么在已经有了临时表的情况下还要引入表变量?
解答 1:与临时表相比,表变量具有下列优点:
问题 2:如果说使用表变量比使用临时表导致存储过程的重新编译更少,这意味着什么?
•
如 SQL Server 联机丛书“表”(Table) 一文中所述,表变量(如局部变量)具有明确定义的范围,在该范围结束时会自动清除这些表变量。
•
与临时表相比,表变量导致存储过程的重新编译更少。
•
涉及表变量的事务仅维持表变量上更新的持续时间。因此,使用表变量时,需要锁定和记录资源的情况更少。因为表变量具有有限的范围并且不是持久性数据库的一部分,所以事务回滚并不影响它们。
解答 2:下面的文章讨论了重新编译存储过程的一些原因:
“由于某些临时表操作引起的重新编译”一节还列出了为避免一些问题(例如使用临时表导致重新编译)而需要满足的一些要求。这些限制不适用于表变量。
表变量完全独立于创建这些表变量的批,因此,当执行 CREATE 或 ALTER 语句时,不会发生“重新解析”,而在使用临时表时可能会发生“重新解析”。临时表需要此“重新解析”,以便从嵌套存储过程引用该表。表变量完全避免了此问题,因此存储过程可以使用已编译的计划,从而节省了处理存储过程的资源。
问题 3:表变量有哪些缺陷?
解答 3:与临时表相比,它存在下列缺陷:
• | 在表变量上不能创建非聚集索引(为 PRIMARY 或 UNIQUE 约束创建的系统索引除外)。与具有非聚集索引的临时表相比,这可能会影响查询性能。 |
• | 表变量不像临时表那样可以维护统计信息。在表变量上,不能通过自动创建或使用 CREATE STATISTICS 语句来创建统计信息。因此,在大表上进行复杂查询时,缺少统计信息可能会妨碍优化器确定查询的最佳计划,从而影响该查询的性能。 |
• | 在初始 DECLARE 语句后不能更改表定义。 |
• | 表变量不能在 INSERT EXEC 或 SELECT INTO 语句中使用。 |
• | 表类型声明中的检查约束、默认值以及计算所得的列不能调用用户定义的函数。 |
• | 如果表变量是在 EXEC 语句或 sp_executesql 存储过程外创建的,则不能使用 EXEC 语句或 sp_executesql 存储过程来运行引用该表变量的动态 SQL Server 查询。由于表变量只能在它们的本地作用域中引用,因此 EXEC 语句和 sp_executesql 存储过程将在表变量的作用域之外。但是,您可以在 EXEC 语句或 sp_executesql 存储过程内创建表变量并执行所有处理,因为这样表变量本地作用域将位于 EXEC 语句或 sp_executesql 存储过程中。 |
问题 4:与临时表或永久表相比,表变量的仅存在于内存中的结构保证了更好的性能,是否因为它们是在驻留在物理磁盘上的数据库中维护的?
解答 4:表变量不是仅存在于内存中的结构。由于表变量可能保留的数据较多,内存中容纳不下,因此它必须在磁盘上有一个位置来存储数据。与临时表类似,表变量是在 tempdb 数据库中创建的。如果有足够的内存,则表变量和临时表都在内存(数据缓存)中创建和处理。
问题 5:必须使用表变量来代替临时表吗?
解答 5:答案取决于以下三个因素:
• | 插入到表中的行数。 |
• | 从中保存查询的重新编译的次数。 |
• | 查询类型及其对性能的指数和统计信息的依赖性。 |
在某些情况下,可将一个具有临时表的存储过程拆分为多个较小的存储过程,以便在较小的单元上进行重新编译。
通常情况下,应尽量使用表变量,除非数据量非常大并且需要重复使用表。在这种情况下,可以在临时表上创建索引以提高查询性能。但是,各种方案可能互不相同。Microsoft 建议您做一个测试,来验证表变量对于特定的查询或存储过程是否比临时表更有效。
发表评论
-
SQL Server复制的缺陷
2011-02-25 13:12 1232SQL Server复制是最常见的 ... -
SQL SERVER 查看当前数据库系统设置概览
2011-02-24 10:43 1323sql server 数据库查看当系统概览可以在“查询”视图中 ... -
SQL 2005 Reporting Service 出现:“提供程序加载失败”(Provider Load failure)的解决方法
2011-02-23 00:28 1410错误描述:操作系统:windows server 2003 E ... -
安装SQL SERVER 2008出现 RebootRequiredCheck Fail 问题解决
2011-01-26 15:09 2689在安装Sql Server 2008 Enterprise时出 ... -
SQLServer和Oracle的常用函数对比
2011-01-12 00:09 9521.绝对值 S:selectabs(-1) value O ... -
用CROSS APPLY解开了困扰我一年多的一个问题
2011-01-11 01:16 1177假设有一个表叫SongsTop ... -
DBCC命令
2011-01-11 01:06 1189今天把DBCC命令都一一使用了一下,做了笔记,防止忘记. 在 ... -
sql server 查看执行效率低下的语句
2011-01-11 00:54 1644就是在测量功能时,先以下命令清除sql server的缓存 ... -
MSSQL 生成編號 --整理帖
2011-01-11 00:48 945-->Title:得到普通流水 ... -
怎样才能充分利用SQL索引
2011-01-11 00:43 749怎样才能充分利用SQL索引 背景:目前WEB的普及太 ... -
MSSQL聚集索引與非技術索引設計指南
2011-01-11 00:41 920(一)聚集索引设计指南 聚集索引基于数据行的键值在表内排序 ... -
索引的魅力
2011-01-11 00:32 903今天有空,来测试一下mssql2005的一条查询语句在聚集索、 ... -
sql server 2005的一些动态函数
2011-01-11 00:23 1063所有对象:SELECT name, object_id, pr ... -
Sql server 国际化的支持,查询乱码
2011-01-11 00:20 2249如果 Sql server 2005 的数据库字符集是非 ... -
SQL Server 2005中使用DDL触发器监控数据库变化
2011-01-11 00:12 1498添加,删除或修改数据库的对象,一旦误操作,可能会导致大麻烦,需 ... -
SQL Server 2005系列教学_ 触发器
2011-01-11 00:07 1018触发器:本质是一个存储过程 常见的触发器类型:插入触发器 ... -
SQLServer2005新的高效分页方法
2011-01-10 23:58 908Select * FROM ( select ROW_NUM ... -
谈SQL Server标识列
2011-01-08 23:30 1295一、标识列的定义以及 ... -
SQL2005误删除数据的恢复方法
2011-01-06 01:56 1321由于同事写错作业脚本,导致昨天晚上系统当中一张重要表的大概2 ... -
SQL SERVER 2005中的同步复制技术
2011-01-06 01:54 1152一、准备工作: 1.建立一个 WINDOWS 用 ...
相关推荐
资源名称: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 表变量和临时表的区别(详细补充篇),需要的朋友可以参考下
考虑使用表变量而不使用临时表。当需要在临时表上显式地创建索引时,或多个存储过程或函数需要使用表值时,临时表很有用。通常,表变量提供更有效的查询处理。
SQL Server 向临时表插入数据,用临时表和表变量代替游标会极大的提高性能,下面有个示例,大家可以参考下
第2章 临时表和表变量 2.1 临时表 局部临时表 全局临时表 2.2 表变量 限制条件 tempdb 范围和可见性 事务上下文 统计信息 2.3 tempdb相关的注意事项 2.4 表表达式 2.5 比较临时对象 2.6 ...
说临时表和表变量,这是一个古老的话题,我们在网上也找到很多的资料阐述两者的特征,优点与缺点
未及时包括在本自述文件中的任何有关 SQL Server 2005 和 SQL Server Express 的信息都将发布到 Microsoft 知识库文章 907284 中。 [顶部] 3.0 安装问题 本部分详细介绍此版本中的安装问题。 3.1 现有的 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自带的语法检查功能对数据源语
全书分为23章,涉及到SQLServer2000、SQLServer2005、Access、Oracle10g、MySql5.0和Postgresql8.2等6种数据库语言,内容包括SQL语言基础、常规数据查询、高级数据过滤、字符串查询、日期函数、日期函数、数据排序、...
9.2.2 SQLServer中访问数据的方式 9.3 创建、修改和删除索引 9.3.1 CREATEINDEX语句 9.3.2 创建XML索引 9.3.3 随约束创建的隐含索引 9.3.4 在稀疏列和地理空间列上创建索引 9.4 明智地选择——在何时何地使用何种...
亲,本人纯手工添加了书签哦!!方便阅读 《Microsoft SQL Server 2008技术内幕:T-SQL语言基础》是...10.5 临时表 10.6 动态SQL 10.7 例程 10.8 错误处理 10.9 总结 附录A SQL SERVER使用入门 索引
全书分为23章,涉及到SQLServer2000、SQLServer2005、Access、Oracle10g、MySql5.0和Postgresql8.2等6种数据库语言,内容包括SQL语言基础、常规数据查询、高级数据过滤、字符串查询、日期函数、日期函数、数据排序、...
11.3 临时表 11.4 聚合 11.5 GROUP BY 11.6 HAVING 11.7 独特值 11.8 函数 11.9 RAISERROR 11.10 错误处理 11.11 @@ERROR 11.12 TRY...CATCH 11.13 小结 第12章 高级T-SQL ...
10.6.4 在一个临时表中保存标识值 10.7 GUI 10.8 使用MIN或MAX函数的While循环 10.9 属性管理 10.10 小结 10.11 练习 第11章 与SQL Server环境的交互 11.1 OLE Automation对象的执行 11.1.1 sp-OACreat 11.1.2 sp-...
全书分为23章,涉及到SQLServer2000、SQLServer2005、Access、Oracle10g、MySql5.0和Postgresql8.2等6种数据库语言,内容包括SQL语言基础、常规数据查询、高级数据过滤、字符串查询、日期函数、日期函数、数据排序、...