原文: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. SetCookies, cookie规范注册表和cookie存储将会优先于设置在HTTP客户端级别中默认的那些

    遇到下面问题解决方法: Hey? 404 抱歉,你输入的网址可能不正确,或者该网页不存在. 7 秒后返回首页 使用独立的本地执行上下文来实现对每个用户(或每个线程)状态的管理. 定义在本地内容中的co ...

  2. 中文字符集编码Unicode ,gb2312 , cp936 ,GBK,GB18030

    中文字符集编码Unicode ,gb2312 , cp936 ,GBK,GB18030 cp936是微软自己发布的用在文件系统中的编码方式.而bg2312是中国国家标准.我明白mount -t vfa ...

  3. 两种Data Table参数化设置的区别

    首先介绍Data Table的语法: 1.DataTable.value(ParameterID, SheetID) 2.DataTable(ParameterID, SheetID) 以上2种方法的 ...

  4. Linux从零到高手的进阶心得(转)

    从2006年毕业至今,从事IT行业已经接近8个年头. 一路走来有很多心路历程和技术心得都写在了51CTO的博客中,不少文字现在看来已显稚嫩,但是这正是我真实的成长之路.这八年,从最基础的网络管理员开 ...

  5. HTML CSS——background的认识(一)

    今天回归bug时无意间看到了样式表中background属性,如今总结一下: 1.background-color:设置元素的背景色.其值能够为:color-name.color-rgb.color- ...

  6. iOS8互动的新通知

    iOS8一旦远程通知想必大家都很熟悉.不要做过多的描述在这里,直接推出iOS8交互式远程通知. 再看互动的通知电话,显示的形式                  如今来看一下详细实现方式 一.通过调用 ...

  7. JavaScript 内存

    JavaScript 中对内存的一些了解 在使用JavaScript进行开发的过程中,了解JavaScript内存机制有助于开发人员能够清晰的认识到自己写的代码在执行的过程中发生过什么,也能够提高项目 ...

  8. 【UFLDL】多层神经网络

    请参见原始英文教程地址:http://ufldl.stanford.edu/tutorial/supervised/MultiLayerNeuralNetworks 本文是在学习该教程时记得笔记,供參 ...

  9. 使用JAVASCRIPT实现静态物体、静态方法和静态属性

    Javascript语言的面向对象特征非常弱.其它面向对象语言在创建类时仅仅要使用keywordstatic就可以指定类为静态类,Javascript没有提供static这种keyword.要让Jav ...

  10. iOSSingleton设计模式详细的说明教程

    iOS有很多的设计模式,当然,不管是什么语言有很多的设计模式.辛格尔顿是一种之一,辛格尔顿,它从字面上是一个单独的实例,首先,它是只有一个单一的,其次,它是一个实例.我们知道,在iOS用于开发Obje ...