2009-10-22 15 views
8

Bir veritabanındaki bir tablodaki kayıtları bir arşiv veritabanındaki aynı tabloya arşivlemeye çalışıyorum. Üç yıldan daha eski bir tarihle tüm kayıtlar için bir ek yapabilmem ve sonra bu satırları silmem gerekiyor. Ancak, bu tabloda canlı olarak milyonlarca kayıt vardır, bu yüzden bunu bir seferde yaklaşık 100 ila 1000 parça bir döngü içinde çalıştırmak istiyorum. Şimdiye kadar saklı yordam tüm insert deyimini, daha sonra insert deyimiyle esas olarak aynı WHERE yan tümcesiyle bir deyimde (bir işlemde) silme işlemini yapar. WHILE döngüsüm, döngüün ne zaman tamamlandığını belirlemek için tablodaki en eski tarihi arıyor. Bunlardan bazıları oldukça verimsiz görünüyor. Aynı döngü uygulamasında iki kez bakmak zorunda kalmadan kayıtların bir parçasını ekleyip silmem mümkün mü? WHILE ifadesinin ne zaman tamamlandığını belirlemenin daha iyi bir yolu var mı? MS SQL Server 2000SQL Arşiv Komut Dosyası

Running Bu benim şimdiki Prosedürü (ISAdminDB ana DB ise, ISArchive arşiv DB ise): Öncelikle

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

RDBMS? SQL Server, MySQL, başka bir şey? – MartW

+0

Özür dileriz, MS SQL Server 2000. – Kevin

+0

SQL Server'ı tahmin ediyorum – MartW

cevap

6

, sen 3, belirli bir tarihten önce kayıtları siliyoruz Yıllar önce. Silmekte oldukları emrin ne olduğu umrumda değil, sadece sol kalmayıncaya kadar bunları silmeye devam etmeniz gerekiyor. Ayrıca, kimlikleri saklamak için geçici bir tablo kullanarak ve kesme tarihini bir değişkende saklayarak ve tekrar tekrar ona başvurarak da hızlandırabilirsiniz.

Yani şimdi var:

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

Teşekkürler! Girişini takdir ediyorum. Çalışıyor gibi görünüyor. – Kevin

İlgili konular