2010-07-09 4 views
4

J'ai une boucle qui exécute la procédure stockée dans une boucle avec plus de 40 000 itérations, comme suit:Appel sqlCommand dans une boucle de plus en plus de temps à chaque étape exec

SqlCommand command = new SqlCommand("WriteDataToDB"); 
     command.Connection = _connection; 
     command.CommandType = CommandType.StoredProcedure; 

     command.Parameters.Add("@SignalID", SqlDbType.Int).Value = Arg_Signal.SignalID; 
     command.Parameters.Add("@SignalStrength", SqlDbType.Float).Value = Arg_Signal.SignalSiggestion; 
     command.Parameters.Add("@Time", SqlDbType.BigInt).Value = Arg_Signal.TimeWasHit; 
     command.Parameters.Add("@Value", SqlDbType.Float).Value = Arg_Signal.ValueWasHit; 

     if (command.Connection.State != ConnectionState.Open) 
     { 
      command.Connection.Open(); 
     } 
     command.ExecuteNonQuery(); 

Ce code est appelé à partir d'une boucle où J'intercepte et chronomètre toutes les 1000 itérations. Les temps que je reçois sont ci-dessous:

[0]: "Commencé 0ms" [1]: "1000 578.125ms DONE"

[2]: "1000 921.875ms DONE"

[3 ]: "1000 1328.125ms Terminé"

[4]: ​​"1000 1734.375ms Terminé"

[5]: "1000"

1140.625ms done

[6]: "1000 Done 1250ms"

[7]: "1000 1703.125ms Terminé"

[8]: "1000 1718.75ms Terminé"

......

[31]: « 1000 fait 3234,375 ms "

[32]: "1000 3390.625ms Terminé"

[33]: "1000 3453.125ms Terminé"

[34]:" 1000 fait 3609,375 ms »

[35]: "1000 3765.625ms Terminé"

[36]: "1000 3796.875ms Terminé"

[37]: "1000 3968.75ms Terminé"

[38 ]: "1000 4093.75ms DONE"

[39]: "1000 4203.125ms DONE"

[40]: "1000" done 4546.875ms

[41]: "1000 4406.25ms DONE"

[42]: "Nous nous sommes arrêtés avec 101093.75ms au total 1515.625ms"

Est-ce que quelqu'un a une idée pourquoi ces temps d'exécution augmentent? Je dois exécuter ce code avec plus d'un million d'itérations - par le taux sa va sa va prendre une minute pour exécuter une itération ...

Un grand merci

Répondre

1

Y a-t-il une logique spéciale dans votre proc stocké ou vous insérez simplement dans une table.

S'il n'y a pas de logique particulière ou si vous pouvez faire cette logique dans .NET, jetez un coup d'œil à l'exécution de Bulk Insert. Vous pouvez le faire en utilisant la classe System.Data.SqlClient.SqlBulkCopy.

+1

Il y en a réellement. Le proc stocké détermine d'abord si l'enregistrement existe et l'insère ou le met à jour. J'ai ajouté un index qui couvre les colonnes sur lesquelles il est recherché, et a obtenu un temps d'exécution uniforme, avec des temps multipliés par 20. Merci! – Michael

+0

Cela rend compte de vos résultats à mesure que la taille de votre table augmente, tout comme le temps nécessaire pour effectuer une analyse de table. :) –

+0

@Michael, alors peut-être un indice judicieux est en ordre? –

0

Je ne peux pas dire que je sais pourquoi vous il ralentit à chaque fois (il semblerait que vous n'effacez pas le "1000" à chaque fois, mais que vous l'ajoutiez ou quelque chose), mais si vous cherchez à vider les données dans une base de données, vous devriez utiliser quelque chose comme SqlBulkCopy proc à l'intérieur d'une boucle for.

0

Ceci est juste une supposition, mais vous ajoutez plus de paramètres à chaque itération.Oui, ils ont les mêmes noms qu'avant, mais je ne sais pas si la classe SqlCommand est assez intelligente pour gérer ça ou pas. Essayez d'ajouter les paramètres une seule fois puis de simplement définir leur valeur dans la boucle, c'est à dire.

En dehors de la boucle:

command.Parameters.Add("@SignalID", SqlDbType.Int); 

intérieur de la boucle:

command.Parameters["@SignalID"].Value = Arg_Signal.SignalID; 

Si cela ne vous aide auriez pas au profil le code et voir où il est lent - il ne peut pas être l'appel DB réel. En outre, vous pouvez aussi appeler command.Prepare() en exécutant plusieurs fois la même commande - cela ne résoudrait pas ce problème particulier, mais pourrait tout de même faire une légère différence de performance pour le mieux.

Questions connexes