Delete和Truncate的區別

2021-09-30 15:17:22 字數 3657 閱讀 1675

一般對於沒有用的資料,都會經行刪除,而刪除通常使用的是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

godelete table [sales].salesorderdetail_j

godelete table [sales].salesorderdetail_f

使用dbcc showcontig命令來檢視資料分布情況:

dbcc showcontig( '[sales].salesorderdetail_d')

godbcc showcontig('[sales].salesorderdetail_j')

godbcc showcontig('[sales].salesorderdetail_f')

結果如下:

從上圖可以看出,堆表(即沒有聚集索引的表)掃瞄出82個頁和11個區,由於已經刪除屬於,所以這些都是空的。而有聚集索引的表,只有1個頁和1個區。有非聚集索引的表,也有66個頁和9個區。

可以看到,沒有聚集索引的表刪除資料後還遺留了不少空間。

下面來看看truncate操作:

同樣,先建立表,使用上面的建表語句建立同樣的表,以保證對比一致性:

drop table sales.salesorderdetail_d

godrop table sales.salesorderdetail_j

godrop table sales.salesorderdetail_fgo

--堆,即沒有聚集索引

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

gotruncate table [sales].salesorderdetail_j

gotruncate 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操作而留下的空間,會在插入時重用。如果覺得這些空間存在不好,那麼可以重建/建立聚集索引來釋放空間。

truncate和delete和drop的異同

相同點 truncate 和不帶 where 子句的 delete,以及 drop 都會刪除表內的資料 不同點 1.truncate 和 delete 只刪除資料不刪除表的結構 定義 drop 語句將刪除表的結構被依賴的約束 constrain 觸發器 trigger 索引 index 依賴於該錶的...

Truncate 和 Delete 的區別

truncate操作同沒有where條件的delete操作十分相似,只是把表裡的資訊全部刪除。主要區別如下 1.無論truncate 大表還是小表速度都非常快。delete 要產生回滾資訊來滿足回滾需求,而 truncate 是不產生的。2.truncate 是ddl 語句進行隱式提交,不能進行回滾...

TRUNCATE和DELETE的區別

1 truncate在各種表上無論是大的還是小的都非常快。如果有rollback命令delete將被撤銷,而truncate則不會被撤銷。2 truncate是乙個ddl語言,向其他所有的ddl語言一樣,他將被隱式提交,不能對truncate使用rollback命令。3 truncate將重新設定高...