Nibbling Deletes – Intro

o, đơn của bạn đã thành công. Bạn đang nhận được rất nhiều thứ và rất nhiều giao thông. Chỉ có, nó tăng nhanh hơn dự kiến, và sau một chút tính toán, bạn đã xác định rằng nếu xu hướng hiện tại vẫn tồn tại, bạn sẽ có 24 TB dữ liệu trong vòng 1 năm. Chỉ, bạn thực sự không cần dữ liệu> 3 tháng tuổi trong các bảng OLTP chính.

Câu hỏi: Làm thế nào để bạn lưu trữ, hoặc nuke rằng dữ liệu cũ hơn mà không ảnh hưởng đến hiệu suất? Cố gắng xóa một lượng lớn dữ liệu cùng một lúc sẽ khóa bảng của bạn, sẽ chặn các luồng, sẽ ngăn chặn ứng dụng của bạn và gây ra tất cả các loại đau buồn.

Nhập trình xóa ‘nibbling’ – một thủ thuật mà tôi đã đưa ra để lưu trữ dữ liệu ‘traffic’ trên một máy chủ rất bận rộn (0,3-10 triệu hàng / ngày). Trong tình huống của tôi, một chỉ mục nhóm không tồn tại dọc theo tên miền ngày của đối tượng được đề cập, vì vậy cố gắng xử lý nhiều khóa trên cơ sở cấp hàng (cho một khoảng cách, dựa trên ngày, xóa) sẽ có máy chủ đến đầu gối của nó (tốt, có thể đã nấc lên nó cho một vài giây ít nhất – và tôi không có khả năng bất kỳ interuptions).

Các khái niệm chính: Sql Server có thể, và sẽ, làm một công việc tốt chỉ cần loại bỏ một vài hàng tại một thời điểm. Đó là khi bạn cố gắng loại bỏ 40k hoặc 4 triệu tại một nuốt mà nó được cranky. Những gì chúng ta cần là một cách đơn giản để ‘ăn thức ăn’ nó một vài hàng để nibble tại một thời điểm. Khi nó được thực hiện với những hàng, nó có thể có một vài chi tiết. Hạnh phúc, SQL Server cung cấp một cách để thiết lập ‘nibbling’ hoạt động của riêng bạn, với việc sử dụng một số logic đơn giản và sự hỗ trợ của các nhà điều hành WAITFOR. Như sau:

DECLARE @count int
SET @count = 2000

SET ROWCOUNT 2000

WHILE @count = 2000 BEGIN

XÓA T FROM myBigTable
WHERE someCondition = true

SELECT @count = @@ ROWCOUNT
WAITFOR DELAY ‘000: 00: 00.200’

KẾT THÚC
Đơn giản huh? Mệnh đề where có thể đơn giản như một cái gì đó như WHERE recordedDate> @ 30DaysAgo. Tuy nhiên, bạn có thể thấy rằng việc buột tất cả những kết quả đó là quá đắt, vì vậy bạn có thể làm một cái gì đó như:

DECLARE @count int
SET @count = 2000

SET ROWCOUNT 2000

WHILE @count = 2000 BEGIN

XÓA T FROM myBigTable
WHERE targetID IN
(SELECT TOP 2000 targetID
FROM myBigTable VỚI (NOLOCK)
WHERE something = somethingElse)

SELECT @count = @@ ROWCOUNT
WAITFOR DELAY ‘000: 00: 00.200’

KẾT THÚC
Và đó là nó. Việc bắt buộc SQL Server để hạn chế số lượng các thao tác hàng (thông qua việc thiết lập ROWCOUNT) sẽ ngăn chặn nó từ việc gộp rất nhiều Oodles và rất nhiều khóa, nhưng cho phép SQL Server chỉ tiếp tục churning và churning cho đến khi tất cả các hàng được nhắm mục tiêu bị xóa. Cung cấp cho SQL Server 2000 0,2 giây để ‘suy nghĩ’ giữa các hoạt động sẽ cho nó đủ thời gian để đảm bảo rằng bất kỳ hoạt động hàng đợi chống lại xóa nibbling của bạn sẽ đi qua mà không có nhiều chờ đợi (trên một hệ thống lưu lượng truy cập cao một số hoạt động S W xếp hàng sau của bạn , nhưng các ứng dụng gọi không thể thực sự nói sự khác biệt vì họ không bao giờ mất nhiều hơn 0,4 giây để hoàn thành.

Tất nhiên, trong SQL Server 2005, toán tử SET ROWCOUNT đã ngừng hoạt động. Thay vào đó bạn sẽ chỉ cần các nhà điều hành TOP, mà bây giờ chấp nhận các biến:

DECLARE @target int
SET @target = 2000
DECLARE @count int
SET @count = 2000

WHILE @count = 2000 BEGIN

XÓA T FROM myBigTable
WHERE targetID IN
(SELECT TOP @target targetID
FROM myBigTable VỚI (NOLOCK)
WHERE something = somethingElse)

SELECT @count = @@ ROWCOUNT
WAITFOR DELAY ‘000: 00: 00.200’

KẾT THÚC
Và thẳng thắn, đó là một chút sạch hơn dù sao (ví dụ WHERE mainTable.id IN (SELECT TOP # của id từ mainTable)).

Tôi sẽ đăng thêm một chút về điều này sau này, đặc biệt về một số thủ thuật và thủ thuật khác và cách quản lý bảng với các ràng buộc FK (đặc biệt với tính năng CASCADES được bật).

Please give your comments!

Your email address is confidential.

Recent Posts

Recent Comments

    Archives

    Categories

    Meta