2009-05-19 6 views
2

J'écris une procédure stockée qui, une fois terminée, sera utilisée pour analyser les tables de transfert pour les données fausses colonne par colonne.Pourquoi un processus SQLCLR s'exécuterait-il plus lentement que le même côté du client de code

La première étape de l'exercice consistait simplement à balayer la table --- ce que fait le code ci-dessous. Le problème est que ce code s'exécute en 5:45 secondes --- cependant le même code s'exécute comme une application de console (en changeant la chaîne de connexion bien sûr) s'exécute en environ 44 secondes.

using (SqlConnection sqlConnection = new SqlConnection("context connection=true")) 
    { 
     sqlConnection.Open(); 
     string sqlText = string.Format("select * from {0}", source_table.Value); 
     int count = 0; 
     using (SqlCommand sqlCommand = new SqlCommand(sqlText, sqlConnection)) 
     { 
      SqlDataReader reader = sqlCommand.ExecuteReader(); 
      while (reader.Read()) 
       count++; 
      SqlDataRecord record = new SqlDataRecord(new SqlMetaData("rowcount", SqlDbType.Int)); 
      SqlContext.Pipe.SendResultsStart(record); 
      record.SetInt32(0, count); 
      SqlContext.Pipe.SendResultsRow(record); 
      SqlContext.Pipe.SendResultsEnd(); 
     } 
    } 

Cependant, le même code (différent de chaîne de connexion bien sûr) fonctionne dans une application console dans environ 44 secondes (ce qui est plus proche de ce que je me attendais sur le côté client)

Qu'est-ce que je manque sur le côté SP, qui le ferait courir si lentement.

S'il vous plaît noter: Je comprends parfaitement que si je voulais un nombre de lignes, je devrais utiliser l'agrégation count (*) --- ce n'est pas le but de cet exercice.

Répondre

2

Le type de code que vous écrivez est très sensible à l'injection SQL. Plutôt que de traiter le lecteur comme vous l'êtes, vous pouvez simplement utiliser la propriété RecordsAffected pour trouver le nombre de lignes dans le lecteur.

EDIT:

Après avoir fait quelques recherches, la différence que vous voyez est une conception par différence entre la connexion de contexte et une connexion régulière. Peter Debetta a écrit un blog à ce sujet et écrit:

"La connexion au contexte est écrite de telle sorte qu'elle ne récupère qu'une ligne à la fois, donc pour chacun des 20 millions de lignes impaires, le code demandait chaque ligne individuellement. une connexion sans contexte, cependant, il demande 8K de lignes à la fois. "

http://sqlblog.com/blogs/peter_debetta/archive/2006/07/21/context-connection-is-slow.aspx

+0

La question ne portait pas sur hacks d'injection sql, ni obtenir le nombre de lignes --- il était sur la performance du SqlDataReader, ce qui est la raison pour laquelle je l'avertissement inclus d'origine. –

+0

Après avoir fait quelques recherches, la différence que vous voyez est une différence de conception entre la connexion de contexte et une connexion régulière. Peter Debetta a écrit un blog à ce sujet et écrit: "La connexion au contexte est écrite de façon à ne récupérer qu'une ligne à la fois, donc pour chacune des 20 millions de lignes impaires, le code demandait chaque ligne individuellement. connexion -context, cependant, il demande 8K de lignes à la fois. " http://sqlblog.com/blogs/peter_debetta/archive/2006/07/21/context-connection-is-slow.aspx –

1

Eh bien, il semble que la réponse est dans la chaîne de connexion après tout.

context connection=true 

contre

server=(local); database=foo; integrated security=true 

Pour une raison quelconque bizzare, en utilisant la connexion « externe » SP fonctionne presque aussi vite que d'une application de la console (toujours pas aussi l'esprit rapide vous - 55 secondes)

Bien sûr, maintenant l'assemblage doit être déployé comme externe plutôt que sûr --- et cela introduit plus de frustration.

Questions connexes