2012-02-13 30 views
5

Công ty tôi đang làm việc để có một số bảng nhật ký/nhật ký khổng lồ đang được viết cho mỗi 10 giây hoặc lâu hơn với các giao dịch. Tôi muốn sao chép rất nhiều dữ liệu trong bảng này và xóa nó khỏi bảng đó vì khoảng 75% dữ liệu cũ có thể được đặt trong bảng lưu trữ hoặc thứ gì đó, nhưng nếu tôi làm sai và bảng bị khóa nó sẽ là một thảm họa.sao chép dữ liệu ra khỏi một bảng sản xuất khổng lồ

Trong câu hỏi trước, một chàng trai nghĩ ra điều này, tôi muốn biết rằng điều này sẽ không làm hỏng mọi thứ, là gợi ý nolock đủ để giữ an toàn cho tôi và tất cả các bài viết đều hoạt động tốt? Nếu không, tôi nên làm gì?

set identity_insert newtable on 
DECLARE @StartID bigint, @LastID bigint, @EndID bigint 
select @StartID = max(id)+1 
from newtable 

select @LastID = max(ID) 
from oldtable 

while @StartID < @LastID 
begin 
set @EndID = @StartID + 1000000 

insert into newtable (FIELDS,GO,HERE) 
select FIELDS,GO,HERE from oldtable (NOLOCK) 
where id BETWEEN @StartID AND @EndId 

set @StartID = @EndID + 1 
end 
set identity_insert newtable off 
go 
+1

Điều này thật tuyệt vời ngoại trừ kế hoạch xóa các bản ghi cũ của bạn là gì? Không thực sự là một cách để làm điều đó mà không có một số loại khóa xảy ra. – JNK

+0

Vâng, tôi đã làm rõ câu hỏi một chút, vậy cách tốt nhất để xóa các bản ghi cũ trong khi không cản trở hoạt động db bình thường là gì? –

Trả lời

3

Điều hết sức thận trọng trong việc tạo danh sách của bạn có thể là quá tải, nhưng bạn sẽ muốn chạy xóa hàng loạt.

Đối với INSERT, có thể bạn không cần vòng lặp WHILE. Đối với DELETE Mặc dù vậy, tôi sẽ sử dụng một cái gì đó như thế này (điều chỉnh kích thước hàng loạt yêu cầu của bạn):

WHILE 1=1 
BEGIN 
    DELETE TOP (10000) o 
    FROM OldTable o 
    INNER JOIN NewTable N 
     ON o.id = n.id 
    IF @@ROWCOUNT < 10000 BREAK; 
END 

này sẽ DELETE hồ sơ 10k tại một thời điểm miễn là có hồ sơ để xóa.

+0

Tôi đã thực hiện một cái gì đó tương tự trong quá khứ với một bảng lớn, lưu trữ và xóa hồ sơ theo lô . Về cơ bản nó trông giống như mã của bạn nhưng với một "bắt đầu tran" và một "cam kết tran" bên trong vòng lặp while. Sau đó tôi sao lưu, cắt ngắn và thu hẹp nhật ký. –

+0

Nếu anh ta lo lắng về tranh chấp tôi sẽ không thực hiện giao dịch vì điều đó sẽ khóa bảng :) – JNK

+0

Cảm ơn JNK, vì vậy bạn sẽ khuyên tôi nên sao chép trước rồi thực hiện xóa? Tôi có cần phải lo lắng gì nữa không? Xin lỗi, tôi chỉ siêu hoang tưởng, nhưng tôi nghĩ có vẻ như nó sẽ hoạt động. –

0

Một lựa chọn là phân vùng bảng theo giờ (giả sử bạn có một cột DATETIME trong bảng mà mặc định là GETDATE() trên mỗi chèn). Có các phân vùng cho phép bạn thực hiện bảo trì (thả, sao chép, vv) trên các phân vùng cũ hơn mà không ảnh hưởng đến phân vùng hiện tại.

+1

Anh ấy lo ngại về việc khóa bàn đủ lâu để chọn và bạn đang đề xuất thêm một sơ đồ phân vùng? Tôi khá chắc chắn rằng sẽ gây ra một số khóa cũng ... – JNK

+0

@ JNK có nhưng đó có thể là một phần của một thời gian ngừng hoạt động kế hoạch tương lai –

Các vấn đề liên quan