最近,我有一朋友,对我说他的数据库中的很多存储过程,执行都是超时.让我替他看看是什么原因.我一看,原来他的存储过程中用了很多的临时表与变量表.于是我跟他说过犹不及.

在存储过程中使用临时表或变量表,使用的好可以提高速度,使用的不好,可能会起到反作用. 然后给了他几个示例让他自己去看,然后针对自己的数据库进行修改.

那么表变量一定是在内存中的吗?不一定.

通常情况下,表变量中的数据比较少的时候,表变量是存在于内存中的。但当表变量保留的数据较多时,内存中容纳不下,那么它必须在磁盘上有一个位置来存储数据。与临时表类似,表变量是在 tempdb 数据库中创建的。如果有足够的内存,则表变量和临时表都在内存(数据缓存)中创建和处理。

说明:

1) CPU-- 事件(sql语句)使用的 CPU 时间(毫秒)。

2)  Reads--由服务器代表事件读取逻辑磁盘的次数。这些读取操作数包含在语句执行期间读取表和缓冲区的次数。

3) Writes--由服务器代表事件写入物理磁盘的次数。

示例1.变量表

1) 10000条记录

declare @t table
(
id nvarchar(50),
supno nvarchar(50),
eta datetime
)
insert  @t

select top 10000 ID,supno,eta from 表

--cpu :125    reads :13868    writes: 147

--表 '#286302EC'。扫描计数 0,逻辑读取 10129 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。

--表 '表'。扫描计数 1,逻辑读取 955 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
declare @t table
(
id nvarchar(50),
supno nvarchar(50),
eta datetime
)
insert  @t

select top 1000 ID,supno,eta from 表

--    cpu:46    reads:2101     writes:    17    
--表 '#44FF419A'。扫描计数 0,逻辑读取 1012 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
--表 '表'。扫描计数 1,逻辑读取 108 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。

--示例2。临时表:

create table #t
(
id nvarchar(50),
supno nvarchar(50),
eta datetime
)
end
insert #t
select top 10000 ID,supno,eta
from 表
--cpu :125    reads:13883       writes:148    
--表 '#t00000000005'。扫描计数 0,逻辑读取 10129 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
--表 '表'。扫描计数 1,逻辑读取 955 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
create table #t
(
id nvarchar(50),
supno nvarchar(50),
eta datetime
)
insert #t
select top 1000 ID,supno,eta
from 表

--cpu: 62    reads: 2095        writes: 17

--表 '#t00000000003'。扫描计数 0,逻辑读取 1012 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
--表 '表'。扫描计数 1,逻辑读取 108 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。

--示例3。不创建临时表,直接插入到临时表
select top 10000 ID,supno,eta
into #t
from 表

--cpu:31    reads:1947        writes:83

--表 '表'。扫描计数 1,逻辑读取 955 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
select top 1000 ID,supno,eta
into #t
from 表

--cpu: 0    reads: 997        writes:11

--表 '表'。扫描计数 1,逻辑读取 108 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。

从以上的分析中可以看出,如果使用3)方式,则会少建一个临时表.那么IO中的读写也将减少次数.

1)与2)都会有先建临时表的动作,并进行相应的IO读取操作.

从sql语句对服务器的cpu使用上来看,第三种情况cpu使用率也相对较低.

从物理写入磁盘操作来看,第三种情况的物理写入次数较少.

在什么情况下使用表变量来代替临时表:

取决于以下三个因素:

插入到表中的行数。本人认为最好是小于1000行,具体情况具体分析.
从中保存查询的重新编译的次数。
查询类型及其对性能的指数和统计信息的依赖性。

在某些情况下,可将一个具有临时表的存储过程拆分为多个较小的存储过程,以便在较小的单元上进行重新编译。

个人建议,当记录行小于1000行的情况下,应尽量使用表变量,除非数据量非常大(大于1000行)并且需要重复使用表。在这种情况下,可以在临时表上创建索引以提高查询性能。但是,各种方案可能互不相同。

Microsoft 建议您做一个测试,来验证表变量对于特定的查询或存储过程是否比临时表更有效。

sql server 存储过程中使用变量表,临时表的分析(续)相关推荐

  1. SQL Server存储过程中使用表值作为输入参数示例

    这篇文章主要介绍了SQL Server存储过程中使用表值作为输入参数示例,使用表值参数,可以不必创建临时表或许多参数,即可向 Transact-SQL 语句或例程(如存储过程或函数)发送多行数据,这样 ...

  2. SQL Server 存储过程中使用raiserror抛出异常

    转自(SQL Server 存储过程中使用raiserror抛出异常 ) 一 系统预定义错误代码 SQL Server 有3831个预定义错误代码,由master.dbo.sysmessages 表维 ...

  3. sql server存储过程中SELECT 与 SET 对变量赋值的区别

    SQL Server 中对已经定义的变量赋值的方式用两种,分别是 SET 和 SELECT. 对于这两种方式的区别,SQL Server 联机丛书中已经有详细的说明,但很多时候我们 并没有注意,其实这 ...

  4. SQL Server数据库中创建数据表及数据类型操作应用

    创建表 使用的SQL命令:create table 格式: create table table_name ( list_name type() Y|N null yard, ) eg: 创建AM数据 ...

  5. sql server存储过程中解决单引号的问题

    一:目的想在sql中插入''号,例如:select count(*)from user where name='tom'        a)使用转义字符:select char(39)或select ...

  6. php mssql 存储过程 输入参数,MSSQL_SQL Server存储过程中使用表值作为输入参数示例,在2008之前如果我们想要将表作 - phpStudy...

    SQL Server存储过程中使用表值作为输入参数示例 在2008之前如果我们想要将表作为输入参数传递给SQL Server存储过程使比较困难的,可能需要很多的逻辑处理将这些表数据作为字符串或者XML ...

  7. sql 在存储过程中使用事务(转)

    本来想自己写一下,后来发现这个写的比我理解的要好,所以直接拽过来了,链接地址:https://www.cnblogs.com/RascallySnake/archive/2010/05/17/1737 ...

  8. SQL截断增强功能:SQL Server 2019中的静默数据截断

    In this article, we'll take a look into SQL truncate improvement in SQL Server 2019. 在本文中,我们将研究SQL S ...

  9. SQL Server 2019中SQL表变量延迟编译

    In an article, An overview of the SQL table variable, we explored the usage of SQL table variables i ...

最新文章

  1. MFC调用批处理文件(.bat)
  2. WinDbg 调试命令记录二 (基础CLR查看)
  3. 解决IE无法查看源文件问题
  4. mysql程序设计教程_MySQL教程_编程入门教程_牛客网
  5. 计算机寄存器端口,CPU和外设之间的数据传送方式有哪几种
  6. 正确加载 Javascript 和 CSS 到 WordPress
  7. RabbitMQ学习之spring配置文件rabbit标签的使用
  8. 利用logrotate系统工具切割tomcat日志
  9. SaaSpace:25款最佳免费视频编辑软件工具
  10. 2022国内十大工业级三维视觉引导企业一览
  11. android自定义控件(组合控件)相关
  12. 2019北邮网安考研经验
  13. 如何快速集成短信验证码API[图文教程]
  14. 035 导数 微分对应表
  15. Visual Leak Detector内存泄漏检测工具,vld使用及原理
  16. Redis、ES、Nginx和RabbitMQ面试回忆
  17. python收益风险点图_AAVE当前风险与收益是否有偏差?如何评估DeFi投资组合?
  18. 2019.9.2选择更新分离版
  19. Proteus中七段数码管引脚说明
  20. 怎样解除锁定计算机,怎样解除电脑屏幕锁定 教你解除电脑屏幕锁定的方法

热门文章

  1. C语言递归算法将十进制转换为二进制(附完整源码)
  2. C++volatile
  3. QT的QMovie类的使用
  4. 经典C语言程序100例之十五
  5. protobuf string类型_Protobuf3 使用其他消息类型
  6. php mysql source_详解MySQL数据库中有关source命令
  7. node软件环境安装
  8. 本教程针对HBuilder5.0.0,制作日期2014-12-31(从HBuilder工具上获得)
  9. 搭建和测试Android JAVA NDK
  10. insert into 插入空值_MySQL数据库的表中 NULL 和 空值 到底有什么区别呢