J'ai une base de données très volumineuse (~ 100 Go) composée principalement de deux tables que je veux réduire (dont environ 50 millions d'enregistrements). J'ai un DB d'archives mis en place sur le même serveur avec ces deux tables, en utilisant le même schéma. J'essaie de déterminer la meilleure façon conceptuelle de supprimer les lignes de la base de données dynamique et de les insérer dans la base de données d'archives. Dans ce pseudocode est ce que je fais maintenant:Meilleure pratique pour une procédure stockée d'archivage SQL
Declare @NextIDs Table(UniqueID)
Declare @twoYearsAgo = two years from today's date
Insert into @NextIDs
SELECT top 100 from myLargeTable Where myLargeTable.actionDate < twoYearsAgo
Insert into myArchiveTable
<fields>
SELECT <fields>
FROM myLargeTable INNER JOIN @NextIDs on myLargeTable.UniqueID = @NextIDs.UniqueID
DELETE MyLargeTable
FROM MyLargeTable INNER JOIN @NextIDs on myLargeTable.UniqueID = @NextIDs.UniqueID
En ce moment, cela prend 7 minutes lente épouvantablement pour terminer 1000 enregistrements. J'ai testé la suppression et l'insertion, les deux prenant environ. 3,5 minutes à compléter, donc ce n'est pas nécessairement un est radicalement plus inefficace que l'autre. Quelqu'un peut-il souligner quelques idées d'optimisation dans ce domaine?
Merci!
Ceci est SQL Server 2000.
Edit: Sur la grande table il y a un index ordonné en clusters sur le terrain de ActionDate. Il existe deux autres index, mais aucun n'est référencé dans aucune des requêtes. La table Archive n'a pas d'index. Sur mon serveur de test, c'est la seule requête qui arrive sur SQL Server, elle devrait donc avoir beaucoup de puissance de traitement.
code (ce qui fait une boucle en lots de 1000 enregistrements à la fois):
DECLARE @NextIDs TABLE(UniqueID int primary key)
DECLARE @TwoYearsAgo datetime
SELECT @TwoYearsAgo = DATEADD(d, (-2 * 365), GetDate())
WHILE EXISTS(SELECT TOP 1 UserName FROM [ISAdminDB].[dbo].[UserUnitAudit] WHERE [ActionDateTime] < @TwoYearsAgo)
BEGIN
BEGIN TRAN
--get all records to be archived
INSERT INTO @NextIDs(UniqueID)
SELECT TOP 1000 UniqueID FROM [ISAdminDB].[dbo].[UserUnitAudit] WHERE [UserUnitAudit].[ActionDateTime] < @TwoYearsAgo
--insert into archive table
INSERT INTO [ISArchive].[dbo].[userunitaudit]
(<Fields>)
SELECT <Fields>
FROM [ISAdminDB].[dbo].[UserUnitAudit] AS a
INNER JOIN @NextIDs AS b ON a.UniqueID = b.UniqueID
--remove from Admin DB
DELETE [ISAdminDB].[dbo].[UserUnitAudit]
FROM [ISAdminDB].[dbo].[UserUnitAudit] AS a
INNER JOIN @NextIDs AS b ON a.UniqueID = b.UniqueID
DELETE FROM @NextIDs
COMMIT
END
Avez-vous un index clusterisé dans le champ de clé primaire? – feihtthief
NextID est une variable de table ou une table temporaire? S'il s'agit d'une variable de table, essayez plutôt une table temporaire. J'ai eu des problèmes de performances avec les variables de table dans SQL Server 2000; mais pas si mal. –
NextID est actuellement déclaré en tant que variable de table. Je vais essayer d'utiliser une table temporaire. – Kevin