Delete和Truncate的区别
一般对于没有用的数据,都会经行删除,而删除通常使用的是DELETE和TRUNCATE命令。对于有条件地删除,基本上就会使用DELETE,当然还是没有绝对,用TRUNCATE也可以实现,只要把【不需要】删除的数据插入新表,然后truncate源表,再把数据导回来或者直接重命名新表就可以了。
下面例子主要比较全表删除的情况下DELETE
和TRUNCATE 之间的差异:
首先,先创建测试用例:本例使用AdventureWorks数据库。先创建3个表:
--堆,即没有聚集索引
SELECT * INTO Sales.SalesOrderDetail_D FROM Sales.SalesOrderDetail --有聚集索引
SELECT * INTO Sales.SalesOrderDetail_J FROM Sales.SalesOrderDetail CREATE CLUSTERED INDEX Clustered_SalesOrderDetail_J ON Sales.SalesOrderDetail_J (SalesOrderID,SalesOrderDetailID)
GO
--没有聚集索引,但有非聚集索引
SELECT * INTO Sales.SalesOrderDetail_F FROM Sales.SalesOrderDetail CREATE NONCLUSTERED INDEX Nonclustered_SalesOrderDetail_F ON Sales.SalesOrderDetail_F (SalesOrderID,SalesOrderDetailID)
GO
查看一下各个表的索引情况:
sp_helpindex '[Sales].SalesOrderDetail_D';
GO
结果:

sp_helpindex '[Sales].SalesOrderDetail_J';
GO
结果:

sp_helpindex '[Sales].SalesOrderDetail_F'
结果:

然后,用DELETE对三个表进行清空操作:
DELETE TABLE [Sales].SalesOrderDetail_D GO DELETE TABLE [Sales].SalesOrderDetail_J go DELETE TABLE [Sales].SalesOrderDetail_F
使用DBCC SHOWCONTIG命令来查看数据分布情况:
DBCC SHOWCONTIG( '[Sales].SalesOrderDetail_D')
GO
DBCC SHOWCONTIG('[Sales].SalesOrderDetail_J')
go
DBCC SHOWCONTIG('[Sales].SalesOrderDetail_F')
结果如下:

从上图可以看出,堆表(即没有聚集索引的表)扫描出82个页和11个区,由于已经删除属于,所以这些都是空的。而有聚集索引的表,只有1个页和1个区。有非聚集索引的表,也有66个页和9个区。
可以看到,没有聚集索引的表删除数据后还遗留了不少空间。
下面来看看TRUNCATE操作:
同样,先创建表,使用上面的建表语句创建同样的表,以保证对比一致性:
DROP TABLE Sales.SalesOrderDetail_D GO DROP TABLE Sales.SalesOrderDetail_J GO DROP TABLE Sales.SalesOrderDetail_F GO --堆,即没有聚集索引 SELECT * INTO Sales.SalesOrderDetail_D FROM Sales.SalesOrderDetail --有聚集索引 SELECT * INTO Sales.SalesOrderDetail_J FROM Sales.SalesOrderDetail CREATE CLUSTERED INDEX Clustered_SalesOrderDetail_J ON Sales.SalesOrderDetail_J(SalesOrderID,SalesOrderDetailID) GO --没有聚集索引,但有非聚集索引 SELECT * INTO Sales.SalesOrderDetail_F FROM Sales.SalesOrderDetail CREATE NONCLUSTERED INDEX Nonclustered_SalesOrderDetail_F ON Sales.SalesOrderDetail_F(SalesOrderID,SalesOrderDetailID) GO
然后查看相关索引:
sp_helpindex '[Sales].SalesOrderDetail_D'; GO
结果:

sp_helpindex '[Sales].SalesOrderDetail_J'; go
结果:

sp_helpindex '[Sales].SalesOrderDetail_F'
结果:

现在进行清空操作:
TRUNCATE TABLE [Sales].SalesOrderDetail_D GO TRUNCATE TABLE [Sales].SalesOrderDetail_J go TRUNCATE TABLE [Sales].SalesOrderDetail_F
再检查数据分布情况:

可以看到,3个表都已经没有页和区了。
通过上面的对比,可以得出以下结论:
1、
Truncate比Delete所用的事务日志空间更少:
DELETE 是一行一行操作,并且把记录都存进日志文件(说明一下,无论任何恢复模式,都会记录日志)。而TRUNCATE操作,是对一个页操作,在日志中,仅仅记录释放页面的这个动作,而不记录每一行。
2、
Truncate比Delete使用锁通常较少:
DELETE由于是一行一行删除,所以需要对处理的行进行加锁,而且是行锁。TRUNCATE操作由于是对页操作,所以只需要申请页锁或者表锁。
3、
TRUNCATE对表中的所有页都清空:
执行DELETE后,表还是会有空页,但是TRUNCATE则会全部清除。但是TRUNCATE会保留表结构、列、约束、索引等。而DELETE之后,会哦他能够过后台清除空页。
为了更好地删除空间,可以使用以下方法:
(1)、在表中创建聚集索引
(2)、如果所有数据已经不要,那使用TRUNCATE
而不是DELETE,删除后DROP TABLE
。
另外,对于由于DELETE操作而留下的空间,会在插入时重用。如果觉得这些空间存在不好,那么可以重建/创建聚集索引来释放空间。
Delete和Truncate的区别的更多相关文章
- oracle中drop、delete和truncate的区别
oracle中drop.delete和truncate的区别 oracle中可以使用drop.delete和truncate三个命令来删除数据库中的表,网上有许多文章和教程专门讲解了它们之间的异同,我 ...
- 数据库中drop、delete与truncate的区别
数据库中drop.delete与truncate的区别 drop直接删掉表: truncate删除表中数据,再插入时自增长id又从1开始 :delete删除表中数据,可以加where字句. (1) D ...
- mysql 删除表记录 delete和truncate table区别
MySQL中删除表记录delete from和truncate table的用法区别: mysql中有两种删除表中记录的方法: (1)delete from语句, (2)truncate table语 ...
- SQL Server中DELETE和TRUNCATE的区别
DELETE和TRUNCATE语句之间的区别是求职面试中最常见的问题之一.这两条语句都可以从表中删除数据.然而,也有不同之处. 本文将重点讨论这些差异,并通过实例加以说明. TRUNCATE DEL ...
- 详解Oracle DELETE和TRUNCATE 的区别(摘)
语法delete from aa truncate table aa 区别 1.delete from后面可以写条件,truncate不可以. 2.delete from记录是一条条删的,所删除的每行 ...
- MySQL中drop,delete与truncate的区别
drop直接删掉表 truncate删除表中数据,再插入时自增长id又从1开始 delete删除表中数据,可以加where字句. (1) DELETE语句执行删除的过程是每次从表中删除一行,并且同时将 ...
- 详解Oracle DELETE和TRUNCATE 的区别
原文地址:http://www.cnblogs.com/simplefrog/archive/2012/07/30/2615169.html 语法delete from aa truncate tab ...
- ORACLE中DELETE和TRUNCATE的区别
语法 delete from AA truncate table AA 区别 1.delete from后面可以写条件(也就是where子句,delete from AA where aa.列名 = ...
- Oracle DELETE和TRUNCATE 的区别
语法delete from aa truncate table aa 区别 1.delete from后面可以写条件,truncate不可以. 2.delete from记录是一条条删的,所删除的每行 ...
随机推荐
- VS2010,原来还有这些快捷键,果断记下来!
一直认为VS的快捷键跟eclipse比起来差远了,那些由于不知道还有如此多有效却不知的快捷键阿 1. 检查括号匹配(在左右括号间切换): Ctrl +] 2. 选中从光标起到行首(尾)间的代码: Sh ...
- dede 首页或列表页调用文章内容页body内容
在使用dede过程,有的朋友会调调出文章的列表的内容出来,怎么调呢?当然是用dede的传参的数据查询语句了,方法如下: {dede:arclist flag=h typeid=2 row=1 titl ...
- zend studio 10 实现代码自动换行
在一篇zend framework 的PHP编码标准的文章中看到了这么一段: 一行 80 字符以内是比较合适,就是说,ZF 的开发者应当努力在可能的情况下保持每行代码少于 80 个字符,在有些情况下, ...
- pygame系列_游戏中的事件
先看一下我做的demo: 当玩家按下键盘上的:上,下,左,右键的时候,后台会打印出玩家所按键的数字值,而图形会随之移动 这是客观上面存在的现象. 那么啥是事件呢? 你叫我做出定义,我不知道,我只能举个 ...
- 学习NodeJS第一天:node.js介绍
Node.JS 前辈 C 程序猿 Ryan Dahl(http://four.livejournal.com/)工程,根据 Google 著名的开源 JavaScript 发动机 V8 对于二次开发 ...
- spoj Balanced Numbers(数位dp)
一个数字是Balanced Numbers,当且仅当组成这个数字的数,奇数出现偶数次,偶数出现奇数次 一下子就相到了三进制状压,数组开小了,一直wa,都不报re, 使用记忆化搜索,dp[i][s] 表 ...
- 入门git
入门git 0x01前言 既然没有华丽的出场,那就平凡的分享,首先我要说明一点本篇文章针对Git初学者,对我自己学Git的资源的整合,其实本篇索引应该在我写Git系列文章的时候就紧跟着放上索引的, ...
- Visual C++学习笔记1:一定要注意ANSI和UNICODE差额
最近的研究VC++.下载VS2013,根据<Visual C++开发实战系列>首先hello我写了一个常规样品,结果显示乱码编辑框.夜已经折腾型转变.然后总结很明显ANSI和UNICODE ...
- HBuilder之初体验
听闻HTML5定稿了,所以特意去了解了下.文章有提到HTML5的一款IDE(HBuilder,貌似出来好久了,孤陋寡闻....),于是来到官网http://dcloud.io/ ,被演示图震惊了!果然 ...
- SQL server 表数据改变触发发送邮件
今天遇到一个问题,原有生产系统正在健康运行,现需要监控一张数据表,当增加数据的时候,给管理员发送邮件. 领到这个需求后,有同事提供方案:写触发器触发外部应用程序.这是个大胆的想法啊,从来没写过这样的触 ...