广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >SQLSERVER的truncate和delete区别解析
  • 658
分享到

SQLSERVER的truncate和delete区别解析

摘要

目录一:背景1. 讲故事二:区别详解1. 思考2. 观察 delete 的事务日志。3. 观察 truncate 的事务日志。三:GAM 空间管理1. 基本原理四:总结一:

一:背景

1. 讲故事

面试中我相信有很多朋友会被问到 truncate 和 delete 有什么区别 ,这是一个很有意思的话题,本篇我就试着来回答一下,如果下次大家遇到这类问题,我的答案应该可以帮你成功度过吧。

二:区别详解

1. 思考

从宏观角度来说, delete 是 DML 语句, truncate 是 DDL 语句,这些对数据库产生破坏类的语句肯定是要被 sqlserver 跟踪的,言外之意就是在某些场景下可以被回滚的,既然可以被 回滚,那自然就会产生 事务日志,所以从 事务日志 的角度入手会是一个好的办法。

为了方便测试,还是用上一篇的 post 表,创建好之后插入10条记录,参考sql如下:

DROP TABLE dbo.post;
CREATE TABLE post (id INT IDENTITY, content CHAR(1000) DEFAULT 'aaaaaa')

INSERT post DEFAULT VALUES 
Go 10

有了数据之后就可以通过 fn_dblog 函数从 MyTestDB.ldf 中提取事务日志来观察 delete 和 truncate 日志的不同点。

2. 观察 delete 的事务日志。

为了观察 delete 产生的日志,这里用 @max_lsn 记录一下起始点,参考sql如下:

DECLARE @max_lsn VARCHAR(100)
SELECT @max_lsn=[Current LSN] FROM fn_dblog(NULL,NULL)
DELETE FROM post;
SELECT * FROM fn_dblog(NULL,NULL) WHERE [Current LSN] >@max_lsn

从事务日志看, delete 主要做了两件事情。

10 行 delete 记录删除

这里就有一个好奇的地方了,sqlserver 是如何执行删除操作的呢?要回答这个问题需要到数据页上找答案,参考sql如下:

DBCC IND(MyTestDB,post,-1)
DBCC PAGE(MyTestDB,1,240,2)

从图中可以得到如下两点信息, 至少在堆表下 delete 操作并没有删除 Page,第二个是 delete 记录删除只是将 slot 的指针 抹0

有些朋友可能要问,为什么还有对 PFS 的操作呢?很简单它就是用来记录当前页面的 占用空间比率 的,可以看下我的上一篇文章。

3. 观察 truncate 的事务日志。

delete 原理搞清楚之后,接下来看下 truncate 做了什么?参考sql 如下:

DROP TABLE dbo.post;
CREATE TABLE post (id INT IDENTITY, content CHAR(1000) DEFAULT 'aaaaaa')

INSERT post DEFAULT VALUES 
GO 10

DECLARE @max_lsn VARCHAR(100)
SELECT @max_lsn=[Current LSN] FROM fn_dblog(NULL,NULL)
TRUNCATE TABLE dbo.post
SELECT [Current LSN],Operation,Context,AllocUnitName FROM fn_dblog(NULL,NULL) WHERE [Current LSN] >@max_lsn

从图中可以看到,truncate 主要是对 IAM, PFS, GAM 三个空间管理数据页做了修改,并没有涉及到 PAGE 页,那就有一个疑问了,我的PAGE页还在吗?可以用 DBCC IND 看下。

我去,truncate 操作居然把我的 PAGE 页给弄丢了,它是怎么实现的呢? 要想找到答案,大家可以想一想, truncate 是一个 DDL 语句,为了快速释放表数据,它干脆把 postpage 的关系给切断了,如果大家有点懵,画个图大概就是下面这样。

为了验证这个结论,可以用 DBCC PAGE 直接导出 240 号数据页,观察下是不是表中的数据,不过遗憾的是,这个数据页已不归属 post 表了。。。

接下来又得回答另外一个问题,sqlserver 是如何切断的? 这里就需要理解 GAM 空间管理机制。

三:GAM 空间管理

1. 基本原理

GAM 是用来跟踪 区分配 状态的数据页,它是用一个 bit 位跟踪一个 , 在数据库中一个区表示 连续的8个数据页,在 GAM 数据页中,用 1 表示可分配的初始状态,用 0 表示已分配状态,可能大家有点懵,我再画个简图吧。

为了让大家眼见为实,还是用 post 给大家做个演示。

DROP TABLE dbo.post;
CREATE TABLE post (id INT IDENTITY, content CHAR(1000) DEFAULT 'aaaaaa')
INSERT post DEFAULT VALUES 
GO 10

DBCC TRACEON(3604)
DBCC IND(MyTestDB,post,-1)

从图中可以看到,post 表分配的数据页是 240241 号,对应的区号就是 240/8 + 1 = 31,因为 GAM 是用 1bit 来跟踪一个区,所以理论上 GAM 页面偏移 31bit 的位置就标记了该区的分配情况。

这么说可能大家又有点懵,我准备用 windbg 来演示一下,首先大家要记住 GAM 是 mdf 文件中的第三个页面,用 2 表示, 前两个分别是 文件头 和 PFS 页,关于页面的首地址可以用 DBCC PAGE(MyTestDB,1,2,2) 导出来。

0:078> dp 00000009009F8000 +0x60 00000009`009f8060 00000000`005e0000 00000000`00000000 00000009`009f8070 00000000`00000000 00000000`00000000 00000009`009f8080 00000000`00000000 00000000`00000000 00000009`009f8090 00000000`00000000 00000000`00000000 00000009`009f80a0 00000000`00000000 00000000`00000000 00000009`009f80b0 00000000`00000000 00000000`00000000 00000009`009f80c0 d0180000`00001f38 ffffffff`ffffffd1 00000009`009f80d0 ffffffff`ffffffff ffffffff`ffffffff

从输出内容看,那个 0x1f38 就是 bitmap 数组的长度,后面就是 bit 的占用情况,因为在 31 bit 上,我们观察一个 int 就好了,输出如下:

从图中可以看到,全部都是 0 也就说明当前都是分配状态,如果是 1 表示未分配,接下来把 post 给 truncate 掉再次观察 GAM 页。

TRUNCATE TABLE dbo.post;
DBCC PAGE(MyTestDB,1,2,2)

输出如下:

0:117> dp 00000009009F8000+0x60 00000009`009f8060 00000000`005e0000 00000000`00000000 00000009`009f8070 00000000`00000000 00000000`00000000 00000009`009f8080 00000000`00000000 00000000`00000000 00000009`009f8090 00000000`00000000 00000000`00000000 00000009`009f80a0 00000000`00000000 00000000`00000000 00000009`009f80b0 00000000`00000000 00000000`00000000 00000009`009f80c0 d0184000`00001f38 ffffffff`ffffffd1 00000009`009f80d0 ffffffff`ffffffff ffffffff`ffffffff

对比之后会发现由原来的 000000001f38 变成了 400000001f38,可以用 .fORMat 来格式化下。

从图中看 31bit 跟踪的第 31 号区被回收了,也就验证了真的切断了联系。

同样的道理 PFS 偏移的 0n240 位置跟踪的这个页面也是被释放状态。

四:总结

总的来说,delete 操作是将数据页中的每个 slot 指针一条一条的擦掉,每次擦除都会产生一条事务日志,所以对海量数据进行 delete 会产生海量的事务日志,导致你的 日志文件 暴增。而 truncate 是直接切断 post 和 page 的联系,只需要修改几个空间管理页的 bit 位即可。

最后的建议是如果要清空表数据,建议用 truncate table

到此这篇关于SQLSERVER 的 truncate 和 delete 有区别吗?的文章就介绍到这了,更多相关sqlserver truncate 和 delete 区别内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: SQLSERVER的truncate和delete区别解析

本文链接: https://www.lsjlt.com/news/195393.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • SQLSERVER的truncate和delete区别解析
    目录一:背景1. 讲故事二:区别详解1. 思考2. 观察 delete 的事务日志。3. 观察 truncate 的事务日志。三:GAM 空间管理1. 基本原理四:总结一:...
    99+
    2023-02-09
    sqlserver truncate delete 区别 sqlserver truncate truncate delete 区别
  • SQLSERVER 的 truncate 和 delete 区别解析
    目录一:背景1. 讲故事二:区别详解1. 思考2. 观察 delete 的事务日志。3. 观察 truncate 的事务日志。三:GAM 空间管理1. 基本原理四:总结一:背景 1. 讲故事 在面试中我相信有很...
    99+
    2023-02-09
    sqlserver truncate和delete区别 sqlserver truncate truncate和delete区别
  • delete,truncate和drop的区别
    1、truncate和delete只删除数据不删除表的结构(定义),而drop语句将删除表的结构被依赖的约束(constrain),触发器(trigger),索引(index); 依赖于该表的存储...
    99+
    2022-10-18
  • 理论 - DELETE和TRUNCATE区别?
    主要有以下三个:1、DELETE语句,是一个删除标记,并不真正的删除数据,所以,可以通过工具恢复;TRUNCATE语句是直接清空数据行,所以,不能通过工具恢复2、DELETE语句,其ibd文件并不会减小;T...
    99+
    2022-10-18
  • mysql中drop、truncate与delete的区别详析
    目录1. drop:删除数据库2. 对比 TRUNCATE TABLE 和 DELETE FROM3. DDL 和 DML 的说明4.效率对比总结1. drop:...
    99+
    2022-11-13
  • Truncate/Delete/Drop table的特点和区别
    之前一直对Truncate/Delete/Drop认识的不是很清晰,所以特意的翻了一下MySQL5.7 Reference Manual,准备系统的了解一下,这里是一些翻译,外加一点自己的认知。T...
    99+
    2022-10-18
  • oracle中delete drop truncate的用法和区别
          数据库的运维中,经常会遇到delete drop truncate的操作,那么如何去把握它们的用法和区别呢?   比如当数据库空间爆满...
    99+
    2022-10-18
  • delete、truncate、drop的区别是什么
    delete、truncate、drop的区别是什么,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。MySQL删除数据的方式都有哪...
    99+
    2022-10-18
  • mysql中的delete,drop和truncate有什么区别
    目录前言:1.delete1.1 delete 实现原理1.2 关于自增列2.truncate2.1 truncate 实现原理2.2 重置自增列3.drop4.三者的区别...
    99+
    2022-11-13
  • mysql中的delete,drop和truncate有哪些区别
    这篇文章主要讲解了“mysql中的delete,drop和truncate有哪些区别”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“mysql中的delete,drop和trunca...
    99+
    2023-07-02
  • MySQL TRUNCATE 和 DELETE 命令有什么区别?
    众所周知,TRUNCATE 将删除所有行,而不从数据库中删除表的结构。可以借助 DELETE 命令完成相同的工作,从表中删除所有行。但这两个命令之间的 PRIMARY KEY AUTO_INCRMENT 重新初始化存在显着差异。假设...
    99+
    2023-10-22
  • mysql中truncate及delete命令的区别
    这篇文章主要介绍“mysql中truncate及delete命令的区别”,在日常操作中,相信很多人在mysql中truncate及delete命令的区别问题上存在疑惑,小编查阅了各式资料,整理出简...
    99+
    2022-10-18
  • drop、truncate与delete的区别是什么
    这篇文章将为大家详细讲解有关drop、truncate与delete的区别是什么,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。注意:这里说的delete是指...
    99+
    2022-10-18
  • sql中delete和truncate之间有什么区别
    这篇文章给大家分享的是有关sql中delete和truncate之间有什么区别的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。在SQL中delete命令和truncate命令都可用...
    99+
    2022-10-18
  • drop、truncate、delete之间的区别是什么
    这篇文章主要介绍“drop、truncate、delete之间的区别是什么”,在日常操作中,相信很多人在drop、truncate、delete之间的区别是什么问题上存在疑惑,小编查阅了各式资料,...
    99+
    2022-10-18
  • SQL命令delete和truncate之间有哪些区别
    这篇文章主要介绍SQL命令delete和truncate之间有哪些区别,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完! 在SQL中delete和truncate命令...
    99+
    2022-10-18
  • mysql中drop、truncate与delete的区别是什么
    本篇内容介绍了“mysql中drop、truncate与delete的区别是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!1....
    99+
    2023-06-29
  • MySQL深入详解delete与Truncate及drop的使用区别
    目录一、删除的内容deletetruncatedrop drop二、删除过程三、表和索引所占空间四、应用范围五、删除程度六、处理速度七、语句类型:八、语法区别九、总结deletetruncatedrop参考文章...
    99+
    2022-07-25
    MySQLdelete MySQLTruncate MySQLdrop
  • MySQL删除方法delete、truncate、drop的区别是什么
    本文小编为大家详细介绍“MySQL删除方法delete、truncate、drop的区别是什么”,内容详细,步骤清晰,细节处理妥当,希望这篇“MySQL删除方法delete、truncate、dr...
    99+
    2022-10-19
  • RMAN 中delete exipired 和 delete obsolete 的区别
    delete expiredIf you run CROSSCHECK, and if RMAN cannot locate the files, then it updates their re...
    99+
    2022-10-18
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作