2010-07-15 37 views
49

可能有人給我的優點和使用以下兩種語句的利弊的快速概覽:贊成&TRUNCATE的缺點VS DELETE FROM

TRUNCATE TABLE dbo.MyTable 

VS

DELETE FROM dbo.MyTable 

這兩者好像他們當所有事情都說完之後做同樣的事情;但是兩者之間必然存在差異。

回答

70

TRUNCATE不會生成任何回滾數據,這使得它閃電般快。它只是取消分配表使用的數據頁面。

但是,如果您處於事務中並希望「撤消」此刪除的功能,則需要使用DELETE FROM,該功能可以回滾。

編輯: 請注意,以上是不正確的SQL Server(但它確實適用於Oracle)。在SQL Server中,如果您處於事務中並且事務未提交,則可以回滾截斷操作。從SQL Server的角度來看,DELETE FROM和TRUNCATE之間的一個關鍵區別是this: 「DELETE語句一次刪除一行,並在事務日誌中記錄每個刪除行的條目.TRUNCATE TABLE通過釋放數據來刪除數據用於存儲表數據的頁面,並且只記錄事務日誌中的頁面釋放。「

換句話說,TRUNCATE中的日誌記錄較少,因爲只有頁面釋放被記錄在事務日誌中,而用DELETE FROM刪除每行記錄。這是TRUNCATE閃電般的原因之一。

還要注意,從MSDN鏈接中,不能截斷由外鍵約束引用的表,參與索引視圖或通過使用事務複製或合併複製進行發佈的表。

編輯2: 另一個關鍵點是,TRUNCATE TABLE將您的身份重置爲初始種子,而DELETE FROM將繼續從停止的地方遞增。 參考:本羅賓遜的答案。

+3

'TRUNCATE'也可能會破壞 一致性(=不檢查外鍵,並且不觸發觸發器) – nothrow 2010-07-15 14:04:28

+13

@Yossarian - 根據MSDN:「你不能在由FOREIGN KEY約束引用的表上使用TRUNCATE TABLE;相反,使用不帶WHERE子句的DELETE語句「。http://msdn.microsoft.com/en-us/library/aa260621%28SQL.80%29.aspx – dcp 2010-07-15 14:07:14

+4

truncate可以被回退。http:// sqlblog。com/blogs/denis_gobo/archive/2007/06/13/1458.aspx – Dhananjay 2012-07-09 13:10:17

-2

截斷沒有做任何記錄,刪除呢,所以如果你有一噸的記錄,你的反式日誌是巨大的

4

TRUNCATE TABLE不記錄交易。這意味着它對於大型桌子來說閃電般快。缺點是你無法撤消操作。

DELETE FROM記錄在事務日誌中被刪除的每一行,因此操作需要一段時間並導致您的事務日誌急劇增長。好處是如果需要的話你可以撤銷操作。

+2

TRUNCATE已記入日誌,可以像DELETE一樣撤消 - 通過使用ROLLBACK或RESTORE。 – sqlvogel 2011-06-29 11:29:33

+1

僅當您使用事務時,並且如果提交了截斷,則無法回滾。它是DDL並沒有記錄到日誌文件。 – ScaleOvenStove 2011-07-12 18:00:17

+1

有趣的是,這個答覆和標記爲答案的答案几乎相同,但是這被降低爲-1,而標記爲答案的答案爲+7(至少在我寫這篇文章的那一刻)。正如前面提到的@dcp,[this](http://blog.sqlauthority。com/2007/12/26/sql-server-truncate -a-roll-back-using-log-files-after-transaction-session-is-closed /)是一篇很好的文章,它描述了TRUNCATE vs DELETE。 – 2013-09-24 20:22:15

43

在其他的答案沒有提到的另一個關鍵點是,TRUNCATE TABLE重置身份初始種子,而DELETE FROM會從那裏離開遞增攜帶。

1

其基本區別在於它們被記錄的方式。 DELETE和TRUNCATE的記錄方式不同,但都可以以完全相同的方式回滾。所有更改數據的操作都被記錄下來。在SQL Server中,不存在非記錄操作的情況。

2

我相信刪除和截斷只能回滾,如果該操作在執行和顯式事務。否則,您將不得不執行還原以恢復已刪除的數據

7

從安全角度來看,另一個區別是TRUNCATE需要表上的ALTER權限,而DELETE只需要該表的DELETE權限。

-1
$connection = $this->getEntityManager()->getConnection(); 
$connection->exec("Truncate TABLE <tablename>;"); 
+0

請給這段代碼添加一些上下文。 – ppperry 2016-04-24 18:29:31

0

有一件事情是非常重要的(IMO),並沒有提到其他的答案是TRUNCATE需要架構穩定性鎖,Sch-S,而DELETE使用行鎖。讓我們檢查以下內容:

BEGIN TRANSACTION; 

BEGIN TRY 
    -- Truncate below will take LCK_M_SCH_S lock for TABLE_A 
    TRUNCATE TABLE TABLE_A 

    -- Lets say the query below takes 5 hours to execute 
    INSERT INTO 
     TABLE_A 
    SELECT 
     * 
    FROM 
     GIANT_TABLE (NOLOCK) 
END TRY 
BEGIN CATCH 
    IF @@TRANCOUNT > 0 
     ROLLBACK TRANSACTION; 
    THROW 
END CATCH 

IF @@TRANCOUNT > 0 
    COMMIT TRANSACTION; 

現在假設1-2分鐘,這個查詢的開始之後,假設我們試圖執行下列操作:我用NOLOCK條款

SELECT COUNT(*) FROM TABLE_A (NOLOCK) 

通知。你認爲現在會發生什麼?此查詢將等待5個小時。爲什麼?因爲NOLOCK子句需要Sch-S鎖在TABLE_ATRUNCATE子句已經有Sch-S。由於我們尚未提交交易,所以即使在TRUNCATE條款之後,鎖仍然處於開啓狀態。 Sch-S鎖定表格基本上意味着要麼通過添加/刪除列等來更改TABLE_A,要麼將其截斷。你甚至不能執行像下面這樣的東西:

SELECT object_id('TABLE_A') 

這也會持續5個小時。但是,如果將TRUNCATE替換爲DELETE FROM,則會看到表上沒有Sch-S鎖,並且上面的查詢不會被刪除。

0

DELETETRUNCATE之間的另一個區別是表損壞時的行爲。

例如:

DELETE FROM table_name; 

將結束與錯誤:

Msg 3314, Level 21, State 3, Line 1

During undoing of a logged operation in database '...', an error occurred at log record ID(). Typically, the specific failure is logged previously as an error in the Windows Event Log service. Restore the database or file from a backup, or repair the database.

Msg 0, Level 20, State 0, Line 0

A severe error occurred on the current command. The results, if any, should be discarded.

雖然TRUNCATE將工作:

TRUNCATE TABLE table_name; 
-- Command(s) completed successfully. 
1

大綱刪除Vs的截斷的SQL服務器

對於全文藉此連接後:Delete Vs Truncate in SQL Server

enter image description here

/*Truncate - Syntax*/ 
TRUNCATE TABLE table_name 

/*Delete - Syntax*/ 
DELETE FROM table_name 
WHERE some_condition