Khách Tác giả:Derik Hammer (@SQLHammer)
Sự khác biệt giữa TRUNCATE TABLE và DELETE thường bị hiểu nhầm. Tôi tìm cách bác bỏ lầm tưởng rằng không thể quay ngược BẢNG TRUNCATE:
Đọc hướng dẫn sử dụng
Bài báo Sách trực tuyến trên BẢNG TRUNCATE khá mô tả:
“Xóa tất cả các hàng khỏi bảng hoặc các phân vùng được chỉ định của bảng mà không ghi nhật ký các lần xóa hàng riêng lẻ. TRUNCATE TABLE tương tự như câu lệnh DELETE không có mệnh đề WHERE; tuy nhiên, TRUNCATE TABLE nhanh hơn và sử dụng ít tài nguyên hệ thống và nhật ký giao dịch hơn. ”Thực tế là TRUNCATE TABLE sử dụng ít hơn tài nguyên nhật ký giao dịch ngụ ý rằng nó ghi vào nhật ký giao dịch ở một mức độ nào đó. Hãy cùng tìm hiểu số tiền và điều tra khả năng hoàn vốn của nó.
Chứng minh điều đó
Trong một bài đăng trước đó, Paul Randal đã trình bày chi tiết về vấn đề này một cách tỉ mỉ, nhưng tôi nghĩ sẽ rất hữu ích nếu cung cấp các bản tóm tắt rất đơn giản để bác bỏ cả hai yếu tố của huyền thoại này.
BẢNG TRUNCATE có thể được khôi phục lại không?
Việc chứng minh rằng BẢNG TRUNCATE có thể được cuộn lại là đủ dễ dàng. Tôi chỉ cần đặt BẢNG TRUNCATE trong một giao dịch và khôi phục nó.
USE demo; BEGIN TRANSACTION; SELECT COUNT(*) [StartingTableRowCount] FROM [dbo].[Test]; TRUNCATE TABLE [dbo].[Test]; SELECT COUNT(*) [TableRowCountAfterTruncate] FROM [dbo].[Test]; ROLLBACK TRANSACTION; SELECT COUNT(*) [TableRowCountAfterRollback] FROM [dbo].[Test];
Có 100.000 hàng trong bảng và nó trở lại 100.000 hàng sau khi khôi phục:
TRUNCATE TABLE có ghi vào nhật ký không?
Bằng cách thực hiện CHECKPOINT, chúng tôi có được một điểm khởi đầu rõ ràng. Sau đó, chúng tôi có thể kiểm tra các bản ghi nhật ký trước và sau BẢNG TRUNCATE.
USE demo; CHECKPOINT; SELECT COUNT(*) [StartingLogRowCount] FROM sys.fn_dblog (NULL, NULL); TRUNCATE TABLE [dbo].[Test]; SELECT COUNT(*) [LogRowCountAfterTruncate] FROM sys.fn_dblog (NULL, NULL);
Lệnh TRUNCATE TABLE của chúng tôi đã tạo ra 237 bản ghi nhật ký (ít nhất là ban đầu). Đây là những gì cho phép chúng tôi thực hiện khôi phục và cách SQL Server đăng ký thay đổi để bắt đầu.
Còn XÓA thì sao?
Nếu cả DELETE và TRUNCATE TABLE đều ghi vào nhật ký và có thể được khôi phục lại, thì điều gì khiến chúng khác nhau?
Như đã đề cập trong tham chiếu BOL ở trên, BẢNG TRUNCATE chiếm ít tài nguyên hệ thống và nhật ký giao dịch hơn. Chúng tôi đã quan sát thấy rằng 237 bản ghi nhật ký đã được viết cho lệnh TRUNCATE TABLE. Bây giờ, chúng ta hãy xem xét XÓA.
USE demo; CHECKPOINT; SELECT COUNT(*) [StartingLogRowCount] FROM sys.fn_dblog (NULL, NULL); DELETE FROM [dbo].[Test]; SELECT COUNT(*) [LogRowCountAfterDelete] FROM sys.fn_dblog (NULL, NULL);
Với hơn 440.000 bản ghi nhật ký được viết cho DELETE, lệnh TRUNCATE rõ ràng là hiệu quả hơn nhiều.
Kết thúc
TRUNCATE TABLE là một lệnh đã ghi và có thể được khôi phục lại, với lợi thế về hiệu suất rất lớn so với DELETE tương đương. DELETE trở nên quan trọng khi bạn muốn xóa ít hàng hơn số hàng tồn tại trong bảng (vì TRUNCATE TABLE không chấp nhận mệnh đề WHERE). Để biết một số ý tưởng về cách làm cho XÓA hiệu quả hơn, hãy xem bài đăng của Aaron Bertrand, "Chia các thao tác xóa lớn thành nhiều phần".