Question

Je suis en train de créer un travail sur SQL Enterprise Manager 2000 pour copier et supprimer des enregistrements dans plusieurs tables de base de données. Nous avons exécuté une procédure de copie en masse et de suppression stockée directement, mais il est possible qu'elle s'exécute sur des millions de lignes et bloque donc le serveur. J'essayais d'essayer de faire fonctionner le service par tranches de 100 disques à la fois, pour que le serveur ne soit pas bloqué (il s'agit d'une base de données Web active). Je veux que ce service fonctionne une fois par nuit, c'est pourquoi je l'ai mis dans un poste d'agent. Existe-t-il un moyen de mettre en boucle les appels aux procédures stockées qui effectuent réellement la copie et la suppression, puis "sommeil"? entre chaque appel pour donner au serveur le temps de rattraper son retard? Je sais qu'il y a la commande WAITFOR, mais je ne sais pas si cela tiendra le processeur ou le laissera exécuter d'autres requêtes entre-temps.

Merci!

Était-ce utile?

La solution

"Chunkifying" vos suppressions est le moyen préféré pour supprimer des quantités excessives de données sans gonfler les fichiers du journal des transactions. Le message de BradC en est un exemple raisonnable.

Il est préférable de gérer ces boucles au sein d’une procédure stockée unique. Pour étendre ce travail dans le temps, je le garderais toujours dans la procédure. Insérer une WAITFOR dans la boucle mettra une "pause". entre chaque série de suppressions, si vous le jugez nécessaire pour traiter les éventuels problèmes de simultanéité. Utilisez un travail d'agent SQL pour déterminer le moment où la procédure démarre - et si vous devez vous assurer qu'elle s'arrête à une certaine heure, intégrez-la également dans la boucle.

Mon comportement sur ce code serait:

--  NOTE: This is a code sample, I have not tested it
CREATE PROCEDURE ArchiveData

    @StopBy DateTime
    --  Pass in a cutoff time.  If it runs this long, the procedure will stop.
AS

DECLARE @LastBatch  int

SET @LastBatch = 1
--  Initialized to make sure the loop runs at least once


WHILE @LastBatch > 0
 BEGIN

    WAITFOR DELAY '00:00:02'
    --  Set this to your desired delay factor

    DELETE top 1000  --  Or however many per pass are desired
     from SourceTable
    --  Be sure to add a where clause if you don't want to delete everything!

    SET @LastBatch = @@rowcount

    IF getdate() > @StopBy
        SET @LastBatch = 0

 END

RETURN 0

Hmm. La relecture de votre message implique que vous souhaitiez copier les données quelque part avant de les supprimer. Pour ce faire, je mettrais en place une table temporaire. À l’intérieur de la boucle, tout d’abord tronquer la table temporaire, puis copier les clés primaires des éléments TOP N, les insérer dans le fichier "archive". table via une jointure à la table temporaire, puis supprimez la table source également via une jointure à la table temporaire. (Juste un peu plus complexe qu'une suppression directe, n'est-ce pas?)

Autres conseils

Ne vous inquiétez pas de l'attente entre les boucles, SQL Server doit gérer le conflit entre votre travail de maintenance et l'activité habituelle du serveur.

Ce qui cause vraiment le problème dans ce type de situation, c’est que l’ensemble du processus de suppression se déroule en une seule fois, au sein d’une même transaction. Cela fait exploser le journal de la base de données et peut entraîner le type de problèmes que vous pouvez rencontrer.

Utilisez une boucle comme celle-ci pour supprimer des fragments gérables:

DECLARE @i INT
SET @i = 1

SET ROWCOUNT 10000

WHILE @i > 0
BEGIN
    BEGIN TRAN
        DELETE TOP 1000 FROM dbo.SuperBigTable
        WHERE RowDate < '2009-01-01'
    COMMIT

    SELECT @i = @@ROWCOUNT
END
SET ROWCOUNT 0

Vous pouvez utiliser une logique similaire pour votre copie.

WAITFOR laissera les autres processus s’essayer. J'ai utilisé cette technique pour empêcher les gros utilisateurs DELETE de verrouiller la machine. Créez une boucle WHILE, supprimez un bloc de lignes, puis WAITFOR quelques secondes (ou moins, selon le cas).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top