2017-09-12 6 views
0

Je le code ci-dessous pour insérer les non transformés (processed=0) les enregistrements de serveur 1 au serveur 2 (en utilisant des serveurs liés), et une fois inséré, il devrait être mis à jour processed=1procédure stockée est trop lent (en utilisant CURSOR)

Je suis juste en utilisant

requête 1:

INSERT INTO SELECT FROM WHERE processed=0 
UPDATE processed=1 WHERE processed=0 

requête 2:

DECLARE pending_records CURSOR LOCAL FOR 
SELECT FROM WHERE processed=0 

OPEN pending_records 

FETCH NEXT FROM pending_records INTO @UniqueID 

WHILE @@FETCH_STATUS=0 
BEGIN 

INSERT INTO SELECT FROM WHERE [email protected] 

IF @@ROWCOUNT=1 .... UPDATE processed=1 WHERE [email protected] 

FETCH NEXT FROM pending_records INTO @UniqueID 

END 

CLOSE pending_records 

DEALLOCATE pending_records 

Requête 1 est super rapide et la requête en utilisant le curseur est trop lent (prend 30 secondes pour les mises à jour 1 enregistrements)

Je reste loin de la requête 1 parce que s'il y a une défaillance dans la base de données, cela affectera la enregistrements. Remarque: Je ne peux pas utiliser DISTRIBUTED TRANSACTION pour le moment car il nécessite une configuration supplémentaire.

+0

'INSÉREZ DANS SÉLECTION À PARTIR DE LÀ O' ... Les noms des tables peuvent être composés si vous avez peur que nous les arrêtions de vous. Le moins que vous puissiez faire est de rassembler un échantillon qui peut compiler. –

+0

@ZoharPeled je peux. Je viens juste de noter une chose maintenant, sans le 'IF @@ ROWCOUNT = 1 .... UPDATE traité = 1 WHERE UniqueID = @ UniqueID' cela prend seulement 3 secondes pour compléter 400 enregistrements. Avec la commande de mise à jour, cela prend presque 15 minutes (pour 400 enregistrements) – Rauf

+0

Alors s'il vous plaît [modifier] votre question afin que nous puissions voir le code qui a du sens. En outre, il serait probablement utile si nous savions quelle table est sur quel serveur. –

Répondre

0

Vous pouvez essayer ceci: ajouter une colonne supplémentaire à votre table où vous mettez un drapeau de traitement supplémentaire. Générer un GUID au début de votre procédure stockée et mettre à jour votre table:

UPDATE <table> 
SET processing_flag = <GUID> 
WHERE processed = 0; 

Et vous pouvez simplement transférer vos lignes à l'autre serveur par

INSERT INTO <target> 
SELECT <columns> 
FROM <source> 
WHERE processed = 0 AND processing_flag = <GUID>; 

Après cela, vous pouvez ensemble traité = 1 et efface le processing_flag. Si quelque chose échoue, vous pouvez sélectionner toutes les lignes non transférées par traitées = 0 et processing_flag! = NULL.

J'ai eu un problème similaire avec le transfert de lignes simples. En les mettant tous en un, mon problème a été résolu.

Peut-être que votre serveur cible ou la connexion est trop lente aussi.

+0

Je ne peux pas modifier la table, elle est utilisée par une application tierce. – Rauf

+0

Pouvez-vous ajouter une nouvelle table? – user8527410

+0

Quel type de type de données est traité? – user8527410

1

Avez-vous essayé d'utiliser l'argument 'FAST_FORWARD'? 'FAT_FORWARD' spécifie le curseur FORWARD_ONLY, READ_ONLY avec les optimisations de performance activées. FAST_FORWARD ne peut pas être spécifié si SCROLL ou FOR_UPDATE est également spécifié.

En savoir plus here.

+0

Ce serait mon approche aussi ... – taavs