1、临时表

1.1 临时表包括:以#开头的局部临时表,以##开头的全局临时表。

1.2 存储

不管是局部临时表,还是全局临时表,都会放存在tempdb数据库中。

1.3 作用域

局部临时表:对当前连接有效,只在创建它的存储过程、批处理、动态语句中有效,类似于C#语言中局部变量的作用域。

全局临时表:在所有连接对它都结束引用时,会被删除,对创建者来说,断开连接就是结束引用;对非创建者,不再引用就是结束引用。

但最好在用完后,就通过drop  table 语句删除,及时释放资源。

1.4 特性

和普通的表一样,能定义约束,能创建索引,最关键的是有数据分布的统计信息,这样有利于优化器做出正确的执行计划,但同时它的开销和普通的表一样,一般适合数据量较大的情况。有一个非常方便的select ... into 的用法,这也是一个特点。
 
1.5

使用场景:
 
数据量小直接当做中间表使用,数据量较大可以通过优化提高查询效率,对于复杂的查询可以将中间结果放在临时表中以固化执行计划(专治执行计划走错)
 
 
2、表变量
 
2.1 存储
表变量存放在tempdb数据库中。
 
2.2 作用域

和普通的变量一样,在定义表变量的存储过程、批处理、动态语句、函数结束时,会自动清除。
 
2.3 特性

可以有主键,但不能直接创建索引,也没有任何数据的统计信息。
 
2.4 使用场景:小数据量(百条以内) 注意:表变量不受事务的约束,下面的DEMO会演示。
--DEMO 表变量
declare @tb table(col1 int primary key,col2 varchar(10)) begin tran
insert into @tb
select 1,'aa'
rollback tran --虽然上面回滚了事务,但还是会返回1条记录
select * from @tb begin tran
update @tb
set col2= 'bb'
where col1 = 1
rollback tran --返回的数据显示,update操作成功,根本没有回滚
select * from @tb
3、CTE
3.1 内涵
CTE,就是通用表表达式。 3.2 存储
产生的数据一般存储在内存,不会持久化存储。
也可以持久化:
;with cte
as
(
select 1 as v,'aa' as vv
union all
select 2,'bb'
) --把cte的数据存储在tb_cte表
select * into tb_cte
from cte select * from tb_cte; --运用cte,删除数据
;with cte_delete
as
(
select * from tb_cte
) delete from cte_delete where V = 1 --返回1条数据,另一条已删除
select * from tb_cte

当然,在实际运行时,有些部分,比如假脱机,会把数据存储在tempdb的worktable、workfile中,另外,一些大的hash join和排序操作,也会把中间数据存储在tempdb。

 
3.3 作用域

CTE下第一条SQL

3.4 使用场景

递归,SQL逻辑化(重复的部分写到CTE里面,能减少SQL量,增加SQL条理性和可读性) 注意:SQL逻辑化改写并不能固定执行计划(逻辑中间表,实际解析后还是一个SQL)
3.5 特性

在同一个语句中,一次定义,可以多次引用。也可以定义递归语句。其实,本质问题就是,一个语句几千行,语句太复杂了,SQL Server很难做出最优化的执行计划,这确实难为SQL Server了,所以后来就把这个CTE改为,每一小段语句,把结果集通过select into插入到临时表中,因为临时表是有统计信息的,这样最后关联多个临时表。对SQL Server而言,现在有了每个小的结果集的精确的统计信息,那么就自然能做出更为精确的执行计划,执行性能自然上升。

 
CTE递归案例
--目的:通过传入ParentId(=5),返回该记录的所有子节点数据
IF OBJECT_ID('DiGui','U') IS NOT NULL DROP TABLE DiGui
CREATE TABLE DiGui(
Id INT,
ParentId int
)
INSERT INTO dbo.DiGui
( Id, ParentId )
select 4 ,0
union select 5 ,0
union select 7 ,0
union select 2 ,1
union select 8 ,5
union select 15 ,5
union select 9 ,7
union select 14 ,11
union select 30 ,15
union select 23 ,15
union select 41 ,18
union select 104, 23
union select 42 ,30
union select 39 ,30
union select 53 ,39
union select 67 ,39
union select 88 ,39
union select 107, 39 ;with temp ( [Id], [parentid])
as
(
select Id, parentid FROM DiGui WHERE [parentid] = 5
union all
select a.Id, a.parentid
from DiGui a
inner join temp b ON a.[parentid] = b.[Id]
)
select * from temp

转:sqlserver 临时表、表变量、CTE的比较的更多相关文章

  1. SqlServer之表变量和临时表

    表变量: 表变量创建的语法类似于临时表,区别就在于创建的时候,必须要为之命名.表变量是变量的一种, 表变量也分为本地及全局的两种,本地表变量的名称都是以"@"为前缀,只有在本地当前 ...

  2. sqlserver的表变量在没有预估偏差的情况下,与物理表可join产生的性能问题

    众所周知,在sqlserver中,表变量最大的特性之一就是没有统计信息,无法较为准备预估其数据分布情况,因此不适合参与较为复杂的SQL运算.当SQL相对简单的时候,使用表变量,在某些场景下,即便是对表 ...

  3. SqlServer 临时表 与 表变量(转)

    1. 表变量 变量都以@或@@为前缀,表变量是变量的一种,另外一种变量被称为标量(可以理解为标准变量,就是标准数据类型的变量,例如整型int或者日期型DateTime).以@前缀的表变量是本地的,因此 ...

  4. SQL 表变量和临时表

    SQL 表变量和临时表 表变量:存储在内存中,作用域是脚本的执行过程中,脚本执行完毕之后就会释放内存,适合短时间内存储数据量小的数据集. 优点:使用灵活,使用完之后立即释放,不占用物理存储空间 缺点: ...

  5. 【T-SQL系列】临时表、表变量

    临时表临时表与永久表相似,只是它的创建是在Tempdb中,它只有在一个数据库连接结束后或者由SQL命令DROP掉,才会消失,否则就会一直存在.临时表在创建的时候都会产生SQL Server的系统日志, ...

  6. SQL Server中的临时表和表变量 Declare @Tablename Table

    在SQL Server的性能调优中,有一个不可比面的问题:那就是如何在一段需要长时间的代码或被频繁调用的代码中处理临时数据集?表变量和临时表是两种选择.记得在给一家国内首屈一指的海运公司作SQL Se ...

  7. SQL Server中的临时表和表变量

    SQL Server中的临时表和表变量 作者:DrillChina出处:blog2008-07-08 10:05 在SQL Server的性能调优中,有一个不可比拟的问题:那就是如何在一段需要长时间的 ...

  8. SQL Server中临时表与表变量的区别

    我们在数据库中使用表的时候,经常会遇到两种使用表的方法,分别就是使用临时表及表变量.在实际使用的时候,我们如何灵活的在存储过程中运用它们,虽然它们实现的功能基本上是一样的,可如何在一个存储过程中有时候 ...

  9. 存储过程——公用表表达式(CTE)

    目录 0. 背景说明 1. 定义及语法细节 1.1 基本定义 1.2 基本语法 1.3 多个CTE同时声明 1.4 CTE嵌套使用 2. CTE递归查询 2.1 简介 2.2 准备工作 2.3 计算每 ...

  10. Tempdb--关于表变量的一点疑问和测试

    在思考表变量与临时表之间区别时,表变量不会受事务回滚的影响,那么是否意味着表变量无需写入日志呢? 测试方式: 分别对tempdb上的用户表/临时表/表变量 进行10000次插入,查看日志写入次数,使用 ...

随机推荐

  1. 前端组件化Polymer入门教程(7)——Local DOM

    DOM元素的创建和管理被称为本地DOM(Local DOM) 本地DOM模板 如果你需要使用本地DOM,你们需要用<dom-module>并指定一个相匹配的ID. <dom-modu ...

  2. 让 markdown 生成带目录的 html 文件

    安装 npm install -g i5ting_toc 用法 进入 markdown 文件所在的文件夹 举个栗子: 你的sample.md文件放在桌面上 cd /Users/dora/Desktop ...

  3. ffplay源码分析7-播放控制

    本文为作者原创,转载请注明出处:https://www.cnblogs.com/leisure_chn/p/10316225.html ffplay是FFmpeg工程自带的简单播放器,使用FFmpeg ...

  4. SQL Server “复制”表结构,创建_Log表及触发器

    实例效果: 实现表数据的增修删时,记录日志. 1.“复制”现有表, 创建相应的_Log表: (注意点: 通过select union all 的方式,避免了IDENTITY 的“复制”,即如果原表有 ...

  5. android studio 断网使用

  6. Visual Studio 命令提示符

    Visual Studio 命令提示和 SDK 命令提示会自动设置环境变量,使您能够轻松使用 .NET Framework 工具. 在 .NET Framework 4 版 和更高版本中,应使用 Vi ...

  7. SQL 拼接多个字段的值&一个字段多条记录的拼接

    如student表: studentID studentName studentScore 01 Alice 90 02 Bill 95 03 Cindy 100 一.拼接多个字段的值 select ...

  8. [android] 手机卫士号码归属地查询

    使用小米号码归属地数据库,有两张表data1和data2 先查询data1表,把手机号码截取前7位 select outkey from data1 where id=”前七位手机号” 再查询data ...

  9. Hashmat the brave warrior(UVa10055)简单题

    Problem A Hashmat the brave warrior Input: standard input Output: standard output Hashmat is a brave ...

  10. 使用Spring的AbstractRoutingDataSource类来进行拓展多数据源

    1.继承抽象类AbstractRoutingDataSource 通过重写这个抽象类的determineCurrentLookupKey()方法来决定返回哪个数据库. 2.配置多个数据库 <be ...