原文: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. C++基础学习教程(八)

    转载请注明出处:http://blog.csdn.net/suool/article/details/38300117 引入 在进行下一步的学习之前,我们须要厘清几个概念. RAII 首先介绍一个编程 ...

  2. WPF弹性模拟动画

    原文:WPF弹性模拟动画 我们此次将要制作模拟物理中的弹性现象的交互动画,我们让一个小球向鼠标点击位置移动,这个移动的轨迹不是简单的位移,而是根据胡克定律计算得出的. 胡克定律:F=-kd F代表弹性 ...

  3. tarjan+缩点

    B - Popular Cows Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Su ...

  4. java它们的定义ArrayList序列, 大神跳跃

    一个list有两种类型的对象,今天有需求必须责令不同的约会对象,这里是代码 /** *@author xh1991101@163.com */ List<Message> messages ...

  5. Windows Phone开发(45):推送通知大结局——Raw通知

    原文:Windows Phone开发(45):推送通知大结局--Raw通知 为什么叫大结局呢?因为推送通知服务就只有三种,前面扯了两种,就剩下一种--Raw通知. 前面我们通过两节的动手实验,相信大家 ...

  6. Gitclient使用

    1 首次安装gitclient msysgit watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY3h4NTA0NjU5OTg3/font/5a6L5L2T/ ...

  7. Java Evaluate Reverse Polish Notation(逆波兰式)

    表情:: ["2", "1", "+", "3", "*"] -> ((2 + 1) * 3) ...

  8. CentOS 6 安装Oracle11g

    原创作品.从 "深蓝blog" 博客,欢迎转载,请务必注明转载如下源.否则追究其版权责任. 深蓝的blog:http://blog.csdn.net/huangyanlong/ar ...

  9. Hdu 5256 系列转换

    主题链接: HDU5236 代码: #include<iostream> #include<cstdio> #include<cstring> #include&l ...

  10. 将jar要么aar公布到到网mvn 在(使用github作为仓库), 通过gradle dependency 信息集成

    使用Android Studio用户开发,都希望通过maven该方式整合远程仓库jar.aar文件.但如何将这些文件发布它? 发人员都会将jar文件公布到sonatype上,以提供给其它开发人员集成, ...