2009-10-22 8 views
8

Estoy intentando archivar registros de una tabla en una base de datos en una tabla idéntica en una base de datos de archivo. Necesito poder hacer una inserción para todos los registros con una fecha de más de tres años atrás, y luego eliminar esas filas. Sin embargo, esta tabla tiene millones de registros en vivo, por lo que quiero ejecutar esto en un bucle de aproximadamente 100 a 1000 fragmentos a la vez. Hasta ahora, mi procedimiento almacenado hace la instrucción de inserción completa, luego una declaración de eliminación (en una transacción) con esencialmente la misma cláusula WHERE que la instrucción de inserción. Mi ciclo WHILE busca la fecha más antigua de la tabla para determinar cuándo se completa el ciclo. Algo de esto parece bastante ineficiente. ¿Hay alguna manera de hacer una inserción y eliminar en el fragmento de registros sin tener que buscarlos dos veces en la misma ejecución de bucle? ¿Hay una mejor manera de determinar cuándo se completa la instrucción WHILE? Con MS SQL Server 2000.SQL Archive Script

Ésta es mi procedimiento actual (ISAdminDB es la principal base de datos, IsArchive es la base de datos de archivo):

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

Qué RDBMS? SQL Server, MySQL, ¿algo más? – MartW

+0

Disculpas, MS SQL Server 2000. – Kevin

+0

Supongo que SQL Server – MartW

Respuesta

6

En primer lugar, está la eliminación de registros antes de una fecha específica, 3 hace años que. No importa en qué orden se eliminen, solo tiene que seguir eliminándolos hasta que no quede ninguno. También puede acelerar las cosas usando una tabla temporal para almacenar los ID, y almacenando la fecha de corte en una variable y haciendo referencia a ella repetidamente.

así que ahora tenemos:

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

¡Gracias! Aprecio tu aporte. Parece estar funcionando. – Kevin

Cuestiones relacionadas