Tối ưu hiệu năng SQL (phần 2): DELETE

Tiếp theo phần 1 của series bài viết Tối ưu hiệu năng SQL mặc dù chưa nhận được nhiều sự ủng hộ của anh em quý độc giả gần xa nhưng mình vẫn cho ra tiếp phần 2 ngay lập tức vì đây là cái “tha thu” của mình, mình thích thì mình làm thôi :v

Đối với 1 số hệ thống thì anh em cần phải tiến hành Xóa nhiều dòng dữ liệu 1 lúc, cái này đối với các bảng dữ liệu lớn thì thường chạy khá chậm nếu anh em chúng ta cứ đơn thuần gõ ( Giả sử là mình có bảng A với cột dữ liệu C, khi select có thể ra 2000-3000 row)

DELETE FROM A WHERE C = ‘123’

Điều này có thể dẫn đến việc SQL sử dụng TABLE SCAN trên toàn bộ bảng điều này gây hoang mang tột độ cho hệ thống từ lock bảng, chậm, transaction log phát sinh… Nghe thật là mệt mỏi đấy nhỉ :v

717e82c652735200416212b36445f0d441c4dcd5df61e017d1c0c40428d7dcb3

Để tránh điều này ta nên sử dụng TOP với subquery hoặc CTE để tránh việc TABLE SCAN như câu lệnh dưới

SUBQUERY:

DELETE A

FROM (SELECT TOP (5000) *

FROM A WHERE C = ‘123’) A

CTE:

WITH CTE AS (

SELECT TOP (5000) *

FROM A WHERE C = ‘123’

)

DELETE FROM CTE

Cái này anh em áp dụng được cả với cái UPDATE.

Cái trên anh em áp dụng cho mấy cái vài nghìn row thì nghe vẻ ổn rồi đấy nhỉ (y)

1e8294917bcfa0c613d2dd6a6a0a422ff229e1ed346c2072445765f594ada7ba

Thể bây giờ muốn hơn thì sao 😐 Có anh em bảo hệ thống của anh em còn chẳng biết là khi Xóa sẽ có bao nhiều nữa thế thì TOP sao được 😐 Cứ để TOP 1.000.000 à 😐 Thế khác gì để TABLE SCAN :3

À há. Thế lại làm sao bây giờ

34b06a598b9c17589b3297a66a5d690afbcaa237fc3f7e3a6176ec6ce5adf8bdThì sử dụng vòng lặp thôi chứ sao. Thế mà cùng phải hỏi à :v

SELECT 1
WHILE @@ROWCOUNT > 0
BEGIN
DELETE TOP (1000)
FROM A WHERE C = ‘123’
END

Đấy thấy hay chưa :)) Thêm cách nữa tương tự này

DoItAgain:
DELETE TOP (1000)
FROM A WHERE C = ‘123’
IF @@ROWCOUNT > 0
GOTO DoItAgain

Còn mấy kiểu nữa tương tự thì anh em xem trong phần Tham khảo nhé.

Mấy cái này mình đã ứng dụng trong khi triển khai hệ thống bên mình. Ban đầu mình cũng để DELETE bình thường trên bảng dữ liệu lớn, sau 1 thời gian bảng đó lên đến hàng triệu record thì cái câu DELETE kia nó chạy thì ôi thôi VÃI luôn 😐 Còn bây giờ thì cũng ngon ngon rồi :v Nó giờ lại bị chậm câu INSERT =)) Cái này mình sẽ đưa vào phần sau :v

Thân ái và chào tạm biệt

8410729738_3cd2c836a1

Tham khảo

http://www.johnsansom.com/fast-sql-server-delete/

http://sqlblogcasts.com/blogs/simons/archive/2009/05/22/DELETE-TOP-x-rows-avoiding-a-table-scan.aspx

http://dbadiaries.com/how-to-delete-millions-of-rows-using-t-sql-with-reduced-impact

http://stackoverflow.com/questions/2138593/delete-large-amount-of-data-in-sql-server

http://dba.stackexchange.com/questions/1750/methods-of-speeding-up-a-huge-delete-from-table-with-no-clauses

Advertisements

4 thoughts on “Tối ưu hiệu năng SQL (phần 2): DELETE

  1. Pingback: Tối ưu SQL (phần 9): tính tổng các dòng | Code, code and more code

  2. Pingback: Tối ưu SQL phần 8: 1 câu chuyện đơn gian về việc cộng chuỗi | Code, code and more code

  3. Pingback: Tối ưu SQL (phần 7): Chuyện ngắn của ID | Code, code and more code

  4. Pingback: Tối ưu hiệu năng SQL (phần ): Update hay Merge? | Code, code and more code

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s