Take the 2-minute tour ×
Database Administrators Stack Exchange is a question and answer site for database professionals who wish to improve their database skills and learn from others in the community. It's 100% free, no registration required.

I am trying to get a greater understanding on the differences between the DELETE and TRUNCATE commands. My understanding of the internals goes something along the lines of:

DELETE -> the database engine finds and removes the row from the relevant data pages and all index pages where the row is entered. Thus, the more indexes the longer the delete takes.

TRUNCATE -> simply removes all the table's data pages en mass making this a more efficient option for deleting the contents of a table.

Assuming the above is correct (please correct me if not):

  1. How do different recovery modes affect each statement? If there is any effect at all
  2. When deleting, are all indexes scanned or only those where the row is? I would assume all indexes are scanned (and not seeked?)
  3. How are the commands replicated? Is the SQL command sent and processed on each subscriber? Or is MSSQL a bit more intelligent than that?
share|improve this question
2  
There is some related information on DELETE and TRUNCATE in the answers to this question on the utility of TRUNCATE-ing immediately before a DROP. You can also dig around in the log yourself to study the effects of both commands using the technique described in this answer. –  Nick Chammas Dec 13 '12 at 7:10
    
This answer shows the internals of the DELETE and TRUNCATE operations. Also the question demonstrates a particular situation where TRUNCATE works better. –  孔夫子 Dec 13 '12 at 7:32
4  
@idstam TRUNCATE can be rolled back. Nick covers that in his answer to the question he linked. –  Mark Storey-Smith Dec 13 '12 at 8:19
    
Thanks for all the links to the other questions all :) –  Stuart Blackler Dec 13 '12 at 11:10

1 Answer 1

up vote 29 down vote accepted

DELETE -> the database engine finds and removes the row from the relevant data pages and all index pages where the row is entered. Thus, the more indexes the longer the delete takes.

Yes, though there are two options here. Rows may be deleted from nonclustered indexes row-by-row by the same operator that performs the base table deletes. This is known as a narrow (or per-row) update plan:

Per row deletion

Or, the nonclustered index deletions may be performed by separate operators, one per nonclustered index. In this case (known as a wide, or per-index update plan) the complete set of actions is stored in a worktable (eager spool) before being replayed once per index, often explicitly sorted by the particular nonclustered index's keys to encourage a sequential access pattern.

Per index deletion

TRUNCATE -> simply removes all the table's data pages en masse making this a more efficient option for deleting the contents of a table.

Yes. TRUNCATE TABLE is more efficient for a number of reasons:

  1. Fewer locks may be needed. Truncation typically requires only a single schema modification lock at the table level (and exclusive locks on each extent deallocated). Deletion might acquire locks at a lower (row or page) granularity as well as exclusive locks on any pages deallocated.
  2. Only truncation guarantees that all pages are deallocated from a heap table. Deletion may leave empty pages in a heap even if an exclusive table lock hint is specified (for example if a row-versioning isolation level is enabled for the database).
  3. Truncation is always minimally logged (regardless of the recovery model in use). Only page deallocation operations are recorded in the transaction log.
  4. Truncation can use deferred drop if the object is 128 extents or larger in size. Deferred drop means the actual deallocation work is performed asynchronously by a background server thread.

How do different recovery modes affect each statement? Is there is any effect at all?

Deletion is always fully logged (every row deleted is recorded in the transaction log). There are some small differences in the content of log records if the recovery model is other than FULL, but this is still technically full logging.

When deleting, are all indexes scanned or only those where the row is? I would assume all indexes are scanned (and not seeked?)

Deleting a row in an index (using either the narrow or wide update plans shown previously) is always an access by key (a seek). Scanning the whole index for each row deleted would be horribly inefficient. Let's look again at the per-index update plan shown earlier:

Wide plan 2

Execution plans are demand-driven pipelines: parent operators (to the left) drive child operators to do work by requesting a row at a time from them. The Sort operators are blocking (they must consume their whole input before producing the first sorted row), but they are still being driven by their parent (the Index Delete) requesting that first row. The Index Delete pulls a row at a time from the completed Sort, updating the target nonclustered index for each row.

In a wide update plan, you will often see columns being added to the row stream by the base table update operator. In this case, the Clustered Index Delete adds nonclustered index key columns to the stream. This data is required by the storage engine to locate the row to remove from the nonclustered index:

Output list detail

How are the commands replicated? Is the SQL command sent and processed on each subscriber? Or is SQL Server a bit more intelligent than that?

Truncation is not allowed on a table that is published using transactional or merge replication. How deletions are replicated depends on the type of replication and how it is configured. For example, snapshot replication just replicates a point-in-time view of the table using bulk methods - incremental changes are not tracked or applied. Transactional replication works by reading log records and generating appropriate transactions to apply the changes at subscribers. Merge replication tracks changes using triggers and metadata tables.

share|improve this answer
1  
+1 great and thorough answer, Paul! –  Thomas Stringer Dec 13 '12 at 11:42
1  
@StuartBlackler An extent is 8 pages. See msdn.microsoft.com/en-us/library/ms190969(v=sql.105).aspx –  Paul White Mar 14 '13 at 6:14
2  
+1 Great answer. –  Matt M May 16 '13 at 11:37

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.