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记录是一条条删的,所删除的每行 ...
随机推荐
- hdu 4465 Candy(2012 ACM-ICPC 成都现场赛)
简单概率题,可以直接由剩余n个递推到剩余0个.现在考虑剩余x个概率为(1-p)的candy时,概率为C(2 * n - x, x) * pow(p, n + 1) *pow(1 - p, n - x ...
- There is no Action mapped for namespace / and action name UserAction
果断收藏了,说的非常具体.刚開始学习的人常常遇到的问题. There is no Action mapped for namespace / and action name UserAction 在网 ...
- linux环境下的线程的创建问题
pthread_create函数用于创建一个线程 函数原型 #include<pthread.h> int pthread_create(pthread_t *restrict tidp, ...
- linux 除了某个文件或某个目录以外所有删除
rm `ls | grep -v "aa"` //删除除带aa字符串的全部文件 ls | grep -v keep | xargs rm //除keep字符串的以外全删除 r ...
- 黄聪:Microsoft Enterprise Library 5.0 系列教程(五) Data Access Application Block
原文:黄聪:Microsoft Enterprise Library 5.0 系列教程(五) Data Access Application Block 企业库数据库访问模块通过抽象工厂模式,允许用户 ...
- 安装好.net framework后运行慢
表现 系统有时运行慢,尤其是.net程序运行得相当慢 mscorsvw.exe与mscorsvw.exe *32两个进程挂在任务管理器里时不时地占着CPU 解决 运行以下两条命令,加快这两进程的运行, ...
- Composite Design Pattern 设计模式组合
设计模式组合,它能够更类组合在一类,形成一个树状结构. #include <set> #include <iostream> #include <string> u ...
- 使用NSCondition实现多线程同步
iOS中实现多线程技术有非常多方法. 这里说说使用NSCondition实现多线程同步的问题,也就是解决生产者消费者问题(如收发同步等等). 问题流程例如以下: 消费者取得锁,取产品,假设没有,则wa ...
- ASP.NET 应用程序生命周期
1.请求到达IIS服务器,IIS根据文件后缀找到对应的ISAPI(Internet Server API)扩展来处理,这个配置可在网站属性里的“根目录”选项卡中的“配置”里看到.可以看到,ashx.a ...
- Linux Kernel(Android) 加密算法汇总(四)-应用程序调用OpenSSL加密演算法
Linux Kernel(Android) 加密算法总结(三)-应用程序调用内核加密算法接口 讲到了怎样调用内核中的接口的方法. 本节主要是介绍怎样Android C/C++应用程序调用Openssl ...