原文: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的区别的更多相关文章

  1. oracle中drop、delete和truncate的区别

    oracle中drop.delete和truncate的区别 oracle中可以使用drop.delete和truncate三个命令来删除数据库中的表,网上有许多文章和教程专门讲解了它们之间的异同,我 ...

  2. 数据库中drop、delete与truncate的区别

    数据库中drop.delete与truncate的区别 drop直接删掉表: truncate删除表中数据,再插入时自增长id又从1开始 :delete删除表中数据,可以加where字句. (1) D ...

  3. mysql 删除表记录 delete和truncate table区别

    MySQL中删除表记录delete from和truncate table的用法区别: mysql中有两种删除表中记录的方法: (1)delete from语句, (2)truncate table语 ...

  4. SQL Server中DELETE和TRUNCATE的区别

    ​DELETE和TRUNCATE语句之间的区别是求职面试中最常见的问题之一.这两条语句都可以从表中删除数据.然而,也有不同之处. 本文将重点讨论这些差异,并通过实例加以说明. TRUNCATE DEL ...

  5. 详解Oracle DELETE和TRUNCATE 的区别(摘)

    语法delete from aa truncate table aa 区别 1.delete from后面可以写条件,truncate不可以. 2.delete from记录是一条条删的,所删除的每行 ...

  6. MySQL中drop,delete与truncate的区别

    drop直接删掉表 truncate删除表中数据,再插入时自增长id又从1开始 delete删除表中数据,可以加where字句. (1) DELETE语句执行删除的过程是每次从表中删除一行,并且同时将 ...

  7. 详解Oracle DELETE和TRUNCATE 的区别

    原文地址:http://www.cnblogs.com/simplefrog/archive/2012/07/30/2615169.html 语法delete from aa truncate tab ...

  8. ORACLE中DELETE和TRUNCATE的区别

    语法 delete from AA truncate table AA 区别 1.delete from后面可以写条件(也就是where子句,delete from AA where aa.列名 = ...

  9. Oracle DELETE和TRUNCATE 的区别

    语法delete from aa truncate table aa 区别 1.delete from后面可以写条件,truncate不可以. 2.delete from记录是一条条删的,所删除的每行 ...

随机推荐

  1. DIV 居中对齐

    <div style="text-align:center;margin-right:auto;margin-left:auto">

  2. [欧拉回路] hdu 3018 Ant Trip

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3018 Ant Trip Time Limit: 2000/1000 MS (Java/Others) ...

  3. cocos2d 创建一个黑白纹理

    @interface myGrayTexture : CCTexture2D // @param exposure 曝光 +(id) textureWithFile:(NSString*) file ...

  4. 【ArcGIS 10.2新特性】ArcGIS 10.2 for Desktop 新特性(一)

    ArcGIS 10.2 for Desktop是在10.1的成功基础上进行的改进,它的改进包括:性能提升.附加的安全性.40多个新的分析工具.3D功能提高.栅格增强.新的地理数据管理能力以及其它更多的 ...

  5. hdu2242(树形dp+tarjan+缩点)

    hdu2242 http://acm.hdu.edu.cn/showproblem.php?pid=2242 给定n,m表示n个点,m条边 每个点有个权值 问我们删除两某条边(割边)后将图分为两个部分 ...

  6. Java学习之路:详细解释Java解析XML四种方法

    XML如今已经成为一种通用的数据交换格式,它的平台无关性,语言无关性,系统无关性,给数据集成与交互带来了极大的方便. 对于XML本身的语法知识与技术细节,须要阅读相关的技术文献,这里面包含的内容有DO ...

  7. 掌握Java字节码(转)

    Java是一门设计为运行于虚拟机之上的编程语言,因此它需要一次编译,处处运行(当然也是一次编写,处处测试).因此,安装到你系统上的JVM是原生的程序,而运行在它之上的代码是平台无关的.Java字节码就 ...

  8. 轻松管理您的网络password

    在互联网在现在这个时代,,我们注册了很多帐户.支付宝账号password,各种宝账户password.微信,QQ,电话password,购买各种网站,金融password,它是不是让孩子们的鞋子瞬间淡 ...

  9. 【原创】java中的父进程子进程 —— 坑爹的java Runtime.getRuntime().exec

    最近有一个需求,需要用一个java进程启动多个子进程来完成并发任务.由于必须给用户完成任务的反馈,所以需要父进程记录子进程的生命周期. exec方法返回一个Process对象,在当前进程内调用该对象的 ...

  10. 走进C的世界-那些年我们常犯的错---keyword相关

    近期一段时间參加一些面试,发现非常多细节的问题自己已经变得非常模糊了.对一些曾经常常遇到的错误.如今也说不出原因了. 而且在编码过程中也相同犯这些错误. 特别写一个博客来记录这些我们常常遇到的错误.自 ...