2009-10-22 43 views
8

Tôi đang cố lưu trữ các bản ghi từ một bảng trong cơ sở dữ liệu vào một bảng giống hệt trong cơ sở dữ liệu lưu trữ. Tôi cần để có thể làm một chèn cho tất cả các hồ sơ với một ngày lớn hơn ba năm trước, và sau đó xóa những hàng. Tuy nhiên, bảng này có hàng triệu hồ sơ đang hoạt động, vì vậy tôi muốn chạy điều này trong một vòng lặp khoảng 100 đến 1000 khối cùng một lúc. Cho đến nay thủ tục lưu sẵn của tôi thực hiện toàn bộ câu lệnh chèn, sau đó là một câu lệnh xóa (trong một giao dịch) với mệnh đề WHERE giống như câu lệnh chèn. Vòng lặp WHILE của tôi đang tìm ngày cũ nhất trong bảng để xác định khi vòng lặp hoàn tất. Một số điều này có vẻ khá kém hiệu quả. Có cách nào tôi có thể làm một chèn và xóa trên đoạn của hồ sơ mà không cần phải tìm chúng lên hai lần trong cùng một vòng lặp thực hiện? Có cách nào tốt hơn để xác định khi nào câu lệnh WHILE được hoàn thành? Chạy MS SQL Server 2000.Kịch bản lưu trữ SQL

Đây là thủ tục hiện tại của tôi (ISAdminDB là DB chính, ISArchive là DB lưu trữ):

WHILE ((SELECT MIN([MyTable].[DateTime]) FROM [ISAdminDB].[dbo].[MyTable]) < DATEADD(d, -(3 * 365), GetDate())) 
BEGIN 

INSERT INTO [ISArchive].[dbo].[MyTable] 
(<Fields>) 
SELECT TOP 1000 (<Fields>) 
FROM [ISAdminDB].[dbo].[MyTable] 
WHERE 
    [MyTable].[DateTime] < DATEADD(d, -(3 * 365), GetDate()) 
AND UniqueID in (SELECT TOP 1000 UniqueID FROM [ISAdminDB].[dbo].[MyTable] ORDER BY [MyTable].[DateTime] ASC) 

BEGIN TRAN 
DELETE FROM [ISAdminDB].[dbo].[MyTable] 
WHERE [MyTable].[DateTime] < DATEADD(d, -(3 * 365), GetDate()) 
AND (UniqueID in (SELECT TOP 1000 UniqueID FROM [ISAdminDB].[dbo].[MyTable] ORDER BY [MyTable].[DateTime] ASC)) 
COMMIT 

END 
+0

nào RDBMS? SQL Server, MySQL, cái gì khác? – MartW

+0

Xin lỗi, MS SQL Server 2000. – Kevin

+0

Tôi đoán SQL Server – MartW

Trả lời

6

Thứ nhất, bạn xóa hồ sơ sớm hơn một ngày cụ thể, 3 năm trước. Bạn không quan tâm thứ tự chúng bị xóa, bạn chỉ cần tiếp tục xóa chúng cho đến khi không còn bất kỳ thứ tự nào. Bạn cũng có thể tăng tốc độ bằng cách sử dụng một bảng tạm thời để lưu trữ các ID, và bằng cách lưu trữ ngày cut-off trong một biến và liên tục đề cập đến nó.

Vì vậy, bây giờ chúng ta có:

DECLARE @NextIDs TABLE(UniqueID int primary key) 
DECLARE @ThreeYearsAgo datetime 
SELECT @ThreeYearsAgo = DATEADD(d, -(3 * 365), GetDate()) 

WHILE EXISTS(SELECT 1 FROM [ISAdminDB].[dbo].[MyTable] WHERE [MyTable].[DateTime] < @ThreeYearsAgo) 
BEGIN 
    BEGIN TRAN 

    INSERT INTO @NextIDs(UniqueID) 
     SELECT TOP 1000 UniqueID FROM [ISAdminDB].[dbo].[MyTable] WHERE [MyTable].[DateTime] < @ThreeYearsAgo 

    INSERT INTO [ISArchive].[dbo].[MyTable] (<Fields>) 
     SELECT (<Fields>) 
     FROM [ISAdminDB].[dbo].[MyTable] AS a 
     INNER JOIN @NextIDs AS b ON a.UniqueID = b.UniqueID 

    DELETE [ISAdminDB].[dbo].[MyTable] 
    FROM [ISAdminDB].[dbo].[MyTable] 
    INNER JOIN @NextIDs AS b ON a.UniqueID = b.UniqueID 

    DELETE FROM @NextIDs 

    COMMIT TRAN 
END 
+0

Cảm ơn! Tôi đánh giá cao ý kiến ​​của bạn. Có vẻ như đang làm việc. – Kevin

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