2010-11-23 6 views
0

J'ai besoin d'aide pour optimiser la boucle SQL While ci-dessous. Cela demande à ceux qui ont expérimenté cela d'aider s'il vous plaît. Actuellement, mon code T-SQL dure plus de 25 minutes et je voudrais réduire ce temps autant que possible. J'ai été en mesure d'identifier cette boucle comme un problème majeur et j'apprécierais toute aide pour y arriver.Aide pour l'optimisation de SQL While loop

DECLARE @rownumber int 

DECLARE @power_show BIT 

DECLARE @AD_show BIT 

    set @rownumber = 0 

--FOR EACH ROW CONTAINED IN MY TEMPTABLE 

WHILE @rownumber < @rowcounter 

BEGIN 
     set @rownumber = @rownumber + 1 

     -- THE VARIABLES 
     DECLARE @record_no as BIGINT 
     DECLARE @phone_name VARCHAR(30) 
     DECLARE @messagepriority as INTEGER 
     DECLARE @phone_number VARCHAR(30) 
     DECLARE @phone_id BIGINT 
     DECLARE @questionMessage BIGINT 

     SELECT 
@phone_name = n.phone_name, @phone_number =n.phone_number, @messagepriority =n.messagepriority, @phone_id=n.phone_id , 
     @AD_show=n.AD_show, @power_show=n.power_show 
     FROM 
     #temporary_phonetable n WITH(NOLOCK) 
     WHERE n.rownumber = @rownumber 

     --EXECUTE STOREDPROC ADDMESSAGETOQUEUE WHICH RETURNS THE ROWID OF THE NEWLY CREATED ROW, IF ANY 
     SELECT @record_no = sp_queryExecute AddMessageToQueue(@phone_number, @responsemessages, @dateresponsessent, @savednames, @userid,                 un.messagepriority, @responsetype, un.AD_show, un.power_show, @service_provider, @PhoneType) 


     If(@questionid > 0) 
     BEGIN 
      -- EXECUTE STOREDPROC ADDQUESTIONMESSAGE WHICH RETURNS THE ROWID OF NEWLY CREATED ROW, IF ANY 
      SET @questionMessage = sp_queryExecute AddQuestionMessage(@questionid,@phone_id, @record_no, DATEADD(d, 30, GETDATE())) 
     END 

      -- ADD THE NEW ROWID TO THE TEMP TABLE 
      UPDATE #temporary_phonetable SET record_no = @record_no, [email protected] 
      WHERE phone_number = @phone_number AND rownumber = @rownumber 
     END 
+0

Combien d'articles traitez-vous? Êtes-vous sûr qu'il n'y a pas de blocs pendant votre traitement? Est-il possible d'introduire le code sp dans la requête ci-dessus afin que nous puissions voir s'il existe un moyen de faire cette opération de manière basée sur un ensemble? –

Répondre

2

Je ne pense pas que l'optimisation doive prendre place dans votre boucle. Je recommande de vérifier ce qui se passe dans les procédures stockées. La première réponse était correcte en disant que vous devriez déplacer vos déclarations en dehors de la boucle. Mais je ne crois pas que cela permettra d'économiser beaucoup de temps.

Addendum: cela vaut la peine d'essayer de le faire sans utiliser un curseur et avoir à faire une boucle.

+0

convenu-vérifier le SP - j'allais taper cela et vous me battre à elle. – Joe

+0

Avant cette boucle, j'utilise CTES pour filtrer les données jusqu'au point où je dois ensuite effectuer des insertions sur deux tables pour chaque ligne, si la condition est remplie. Si vous regardez, j'appelle deux storedprocs externes dans le lop là. Comment pourrais-je y parvenir sans boucle? – Kobojunkie

+0

@Kobojunkie, je pense que vous pourriez vouloir commencer une autre question sur le code d'avant la boucle while. Je ne peux pas dire à partir de ce que vous dites si vous pouvez éviter d'utiliser un curseur. MAIS en règle générale, vous devriez éviter les curseurs. Cela ne signifie pas que votre problème peut être résolu sans un curseur. Je ne peux tout simplement pas, en toute conscience, suggérer une solution sans faire remarquer que cela vaut toujours la peine d'essayer d'éviter les curseurs. – Ramy

0

ne sachant pas t-sql je vois 2 choses immédiatement. Pourquoi utiliser un While pour une boucle comptée?

  • Utilisez une boucle for (en plsql nous avons curseur boucles spécifiquement pour itérer un curseur)

  • Pourquoi vous déclarant/initialisation vos vars dans la boucle? Peut-être il y a un les déclarer à l'extérieur et les réinitialiser (si besoin est) à l'intérieur de la boucle.

+0

Il n'y a pas de construction de boucle for dans SQL Server. D'ailleurs, la racine du problème est qu'une boucle est ici du tout. –

+0

"Il n'y a pas de construction de boucle pour SQL Server" - erm, il y a une boucle WHILE, mais vous avez raison de dire éviter les boucles. Une approche basée sur un ensemble est meilleure –

+0

@Mitch Évidemment, il y a une boucle WHILE, c'est dans l'exemple de code. Je parlais simplement du premier point de la réponse de Joe. –