2009-07-21 4 views
1

Récemment, nous avons transformé un ensemble de logique de planification C# complexe en procédure stockée SQL CLR (exécutée dans SQL Server 2005). Nous croyons que notre code est un grand candidat SQL CLR parce que:Any Meilleure pratique d'insertion d'enregistrements de table avec procédure de magasin SQL CLR?

  • La logique implique des tonnes de données de SQL Server.
  • La logique est compliquée et difficile à utiliser avec TSQL
  • Il n'y a pas de threading ou de synchronisation ou d'accès aux ressources depuis l'extérieur du sandbox.

Le résultat de notre sp est assez bon jusqu'à présent. Cependant, étant donné que la sortie de notre logique est sous la forme de plusieurs tables de données, nous ne pouvons pas renvoyer un seul ensemble de lignes comme le résultat de sp. Au lieu de cela, dans notre code, nous avons beaucoup d'instructions "INSERT INTO ...." dans les boucles foreach afin de sauvegarder chaque enregistrement de la collection générique C# dans les tables SQL. Lors de l'examen du code, quelqu'un s'est demandé si l'approche SQL INSERT en ligne dans le CLR SQL pouvait causer un problème de perforation, et se demandait s'il existait une autre meilleure façon d'extraire les données (de nos collections génériques C#).

Alors, une suggestion?

Répondre

2

J'ai couru à travers this tout en travaillant sur un projet SQLite il y a quelques mois et j'ai trouvé cela éclairant. Je pense que c'est peut-être ce que vous cherchez.

...

moyen le plus rapide universel à insérer des données en utilisant des constructions ADO.NET standards

Maintenant que les choses lentes est hors de la voie , permet de parler de certains hardcore chargement en vrac. En dehors de SqlBulkCopy et constructions spécialisées impliquant classes ISAM ou insertion en bloc personnalisé d'autres fournisseurs, il n'y a tout simplement pas battre la puissance brute de ExecuteNonQuery() sur une déclaration paramétrés INSERT. Je démontrerai:

internal static void FastInsertMany(DbConnection cnn) 
{ 

    using (DbTransaction dbTrans = cnn.BeginTransaction()) 
    { 

     using (DbCommand cmd = cnn.CreateCommand()) 
     { 

      cmd.CommandText = "INSERT INTO TestCase(MyValue) VALUES(?)"; 

      DbParameter Field1 = cmd.CreateParameter(); 

      cmd.Parameters.Add(Field1); 

      for (int n = 0; n < 100000; n++) 
      { 

       Field1.Value = n + 100000; 

       cmd.ExecuteNonQuery(); 

      } 

     } 

     dbTrans.Commit(); 

    } 

} 
+0

Les réponses qui sont de simples références à des sources externes ne sont pas très utiles. Je préférerais que vous incluiez un résumé du lien externe au cas où le lien serait brisé. Si vous incluez un résumé, votre réponse aura toujours de la valeur. – tvanfosson

+0

J'ai essayé le code sur mon code, et mec, ça fait pas mal de différence! Merci! J'ai changé de forme en utilisant DBTransaction pour SQLTransaction. BTW, je trouve étrange que le code s'exécute plus rapidement lors de la transaction, parce que j'ai explicitement essayé de commenter les instructions de transaction, et le code a couru plus lentement. Je me demande pourquoi. –

+2

Les instructions exécutées sur une base de données SQL sont implicitement exécutées dans une transaction. En déclarant la transaction, vous procédez au regroupement de toutes les instructions afin que SQL Server n'initie pas une transaction distincte pour chaque instruction. J'imagine qu'en plus de cela, SQL peut également optimiser davantage les processus internes, comme la mise à jour des index, en les différant jusqu'à ce que toutes les instructions de la transaction soient complétées. – MyItchyChin

0

Vous pouvez retourner une table avec 2 colonnes (COLLECTION_NAME nvarchar (max), xml CONTENU) rempli autant de lignes que les collections internes que vous avez. CONTENT sera une représentation XML des données de la collection.

Ensuite, vous pouvez utiliser les fonctionnalités XML de SQL 2005/2008 pour analyser le code XML de chaque collection en tables et exécuter vos instructions INSERT INTO ou MERGE sur la table entière.

Cela devrait être plus rapide que les INSERTS individuels dans votre code C#.

Questions connexes