SQLSERVER 临时表和表变量到底有什么区别?

打印 上一主题 下一主题

主题 1036|帖子 1036|积分 3108

一:背景

1. 讲故事

今天和大家聊一套面试中经常被问到的高频题,对,就是 临时表 和 表变量 这俩玩意,如果有朋友在面试中回答的不好,可以尝试看下这篇能不能帮你成功迈过。
二:到底有什么区别

1. 前置思考

不管是 临时表 还是 表变量 都带了 表 这个词,既然提到了 表 ,按推理自然会落到某一个 数据库 中,如果真在一个 数据库 中,那自然就有它的存储文件 .mdf 和 .ldf,那是不是如我推理的那样呢? 查阅 MSDN 的官方文档可以发现,临时表 和 表变量 确实都会使用 tempdb 这个临时存储数据库,而且 tempdb 也有自己的 mdf,ndf,ldf 文件,截图如下:

有了这个大思想之后,接下来就可以进行验证了。
2. 如何验证都存储在 tempdb 中 ?

要想验证其实很简单,sqlserver 提供了多种方式观察。

  • 查询的过程中观察 tempdb 下是否存在 xxx 表。
  • 使用动态管理视图 sys.dm_db_session_space_usage 查询当前sql占用tempdb下的数据页个数。
为了让测试效果明显,我分别插入 10w 条记录观察 数据页 占用情况。

  • 临时表插入 10w 条记录
  1. CREATE TABLE #temp
  2. (
  3.     id INT,
  4.         content CHAR(4000) DEFAULT 'aaaaaaaaaa'
  5. );
  6. GO
  7. INSERT INTO #temp(id)
  8. SELECT TOP 100000
  9.        ROW_NUMBER() OVER (ORDER BY o1.object_id) AS id
  10. FROM sys.objects AS o1,sys.objects AS o2;
  11. GO
  12. SELECT * FROM sys.dm_db_session_space_usage
  13. WHERE session_id=@@SPID;
复制代码

从图中的 user_objects_alloc_page_count=50456 看,当前的 insert 操作占用了 50456 个数据页。
接下来展开 tempdb 数据库以及观察到的 mdf 文件大小,都验证了存储到 tempdb 这个结论。


  • 表变量插入 10w 条记录
因为表变量的特殊性,这里我故意暂停 1min 让查询迟迟得不到结束,在这期间方便展开 tempdb,重启 sqlserver 恢复初始状态后,执行如下 sql:
  1. DECLARE @temp TABLE
  2. (
  3.     id INT,
  4.         content CHAR(4000) DEFAULT 'aaaaaaaaaa'
  5. );
  6. INSERT INTO @temp(id)
  7. SELECT TOP 100000
  8.        ROW_NUMBER() OVER (ORDER BY o1.object_id) AS id
  9. FROM sys.objects AS o1,sys.objects AS o2;
  10. SELECT * FROM sys.dm_db_session_space_usage
  11. WHERE session_id=@@SPID;
  12.   
  13. WAITFOR DELAY '00:01:00'
复制代码

从图中可以看到 表变量 也会占用 5w+ 的数据页并且数据文件会膨胀。
3. 不同点在哪里

对底层存储有了了解之后,接下来按照重要度从高到低来了解一下区别吧。

  • 临时表有统计信息,而表变量没有
所谓的 统计信息,就是对表数据绘制一个 直方图  来掌握数据的分布情况,sqlserver 在择取较优的执行计划时会严重依赖于这个 直方图,由于展开不了 Statistics 列,这里就从执行计划上观察,如下图所示:

  • 临时表下的执行计划

选中 SELECT * FROM #temp WHERE id > 10 AND id 10 AND id

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

道家人

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表