10
votes

Moyen le plus rapide de mettre à jour (peupler) 1 000 000 enregistrements dans une base de données à l'aide de .NET

J'utilise ce code pour insérer 1 million d'enregistrements dans une table vide dans la base de données. Ok donc sans beaucoup de code, je vais commencer à partir du point que j'ai déjà interagi avec des données et lisez le schéma dans un datatable code>:

donc: p> xxx pré>

Et maintenant que nous avons retournédtvialocaldbv11 code> permet de créer un nouveau datatable code> pour être un clone de la table de base de données source: p> xxx pré>

Ce code remplit 1 million d'enregistrements à une base de données SQL intégrée (localDB) dans 5200ms forte>. Le reste du code ne fait que mettre en œuvre la bulkcopopy mais je le posterai de toute façon. P>

 public string UpdateDBWithNewDtUsingSQLBulkCopy(DataTable TheLocalDtToPush, string TheOnlineSQLTableName, string WebConfigConName)
 {
    //Open a connection to the database. 
    using (SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings[WebConfigConName].ConnectionString))
    {
       connection.Open();

       // Perform an initial count on the destination table.
       SqlCommand commandRowCount = new SqlCommand("SELECT COUNT(*) FROM "+TheOnlineSQLTableName +";", connection);
       long countStart = System.Convert.ToInt32(commandRowCount.ExecuteScalar());

       var nl = "\r\n";
       string retStrReport = "";
       retStrReport = string.Concat(string.Format("Starting row count = {0}", countStart), nl);
       retStrReport += string.Concat("==================================================", nl);
       // Create a table with some rows. 
       //DataTable newCustomers = TheLocalDtToPush;

       // Create the SqlBulkCopy object.  
       // Note that the column positions in the source DataTable  
       // match the column positions in the destination table so  
       // there is no need to map columns.  
       using (SqlBulkCopy bulkCopy = new SqlBulkCopy(connection))
       {
          bulkCopy.DestinationTableName = TheOnlineSQLTableName;

          try
          {
             // Write from the source to the destination.
             for (int colIndex = 0; colIndex < TheLocalDtToPush.Columns.Count; colIndex++)
             {
                bulkCopy.ColumnMappings.Add(colIndex, colIndex);
             }
             bulkCopy.WriteToServer(TheLocalDtToPush);
          }

          catch (Exception ex)
          {
             Console.WriteLine(ex.Message);
          }
       }

       // Perform a final count on the destination  
       // table to see how many rows were added. 
       long countEnd = System.Convert.ToInt32(
       commandRowCount.ExecuteScalar());

       retStrReport += string.Concat("Ending row count = ", countEnd, nl);
       retStrReport += string.Concat("==================================================", nl);
       retStrReport += string.Concat((countEnd - countStart)," rows were added.", nl);
       retStrReport += string.Concat("New Customers Was updated successfully", nl, "END OF PROCESS !");
       //Console.ReadLine();
       return retStrReport;
   }
}


11 commentaires

"NOSQL" n'est pas un moteur de base de données spécifique ou un mécanisme de stockage. Quel moteur?


Passer les frais généraux du jeu de données. Si vous devez utiliser des données de données, alors pourquoi ne pas utiliser la fonctionnalité existante MSDN.MicRosoft.com/en -Us / Bibliothèque / HH485668.aspx ?


Peu importe, je vois que vous utilisez cette méthode. Je n'essaierais toujours pas d'utiliser des datates du tout.


@Blam Quelques automatismes ... ne pas déclarer des types de données dans chaque colonne et vous suggérez donc d'utiliser des dictionnaires ou des hashtables? Je veux dire que je suis vraiment pas si bon inventeur, il suffit de tester tout ce que je vois ce que vous pourriez épargner davantage, si environ 20% ou plus peut-être qu'il sera bon de tester aussi


Vous pensez que le seul moyen de taper les données est via DataTable?


@Blam a commencé avec Dictionnaire et cette classe que vous savez probablement que cela pourrait interagir avec n'importe quelle base de données, mais j'ai aimé la table de données (engrenages autocratiques) si je serai plus qu'heureux de voir quoi Vous feriez pour améliorer Pref ..


Quelle partie de DataTable a des frais généraux n'est pas claire? Il suffit de regarder le nombre numéro de méthodes et de propriétés prises en charge.


ok donc faire liste > Table; ... et vérifiez à nouveau? Vous pensez que c'est moins de ressources, puis de l'envoyer au bulk.copy (quoi ici?) Je n'ai aucune idée de la façon de passer autre que DT


7 secondes pour un million d'enregistrements, sans vraiment voir le problème.


Je pensais la même chose. Je ne faisais que tester cette même option pour certains travaux de l'ETL que je dois faire - sur mon I7, 16 Go de RAM et SSD, j'ai pu obtenir 10 000 000 enregistrements à insérer dans environ 65 secondes, de sorte que ces chiffres semblent assez précis.


Au lieu de ScalareReader - Utilisez un lecteur de données avant seulement - SQLDatreader MyReader = myCommand.executereader ();


8 Réponses :


2
votes

Avez-vous essayé SSIS? Je n'ai jamais écrit de paquet SSIS avec une connexion LOACLDB, mais c'est le type d'activité SSIS devrait être bien adapté.

Si votre source de données est un serveur SQL, une autre idée serait la configuration d'un serveur lié. Je ne sais pas si cela fonctionnerait avec localDB. Si vous pouvez configurer un serveur lié, vous pouvez contourner le C # ensemble et charger vos données avec un insert .. Sélectionnez ... Dès ... Déclaration SQL.


4 commentaires

Pourriez-vous être plus précis de savoir comment suggéreriez-vous la mise en œuvre des SSIS avec mon code, est-ce un code de serveur, est-ce que cela ressemble à la procédure ou comment fonctionne-t-il pour que vous ayez l'idée d'aider à réduire la tâche effectuée par C #


Si je lis correctement votre code, vous remplissez des données d'une base de données source, puis en chargement dans la destination. Je pense que avec SSIS, vous pouvez sauter les données de données et pomper directement à la destination. SSIS (SQL Server Integration Services) est une plate-forme d'intégration de données fournie avec SQL Server.


Bien sûr, merci Mike .. Je vais "faire des recherches" l'approche SSIS, j'en examine un coup d'œil, bien qu'il ait besoin de plus de temps dépensé (plus de 2 minutes (:) pour comprendre Consort et Ucase, etc., comme je je ne suis pas informé de son existence jusqu'à maintenant je suis sûr que je pouvais au moins comprendre ce qu'il s'agit de


Il existe un concepteur visuel pour les SSIS intégrées à Visual Studio. Vous devrez faire une petite recherche, mais pour le déplacement de données en vrac, rien ne se rapproche de la performance.



0
votes

essayez de l'envoyer sans le stocker dans un jeu de données.

Voir l'exemple à la fin de cet article, qui vous permet de le faire avec un énumérateur http://www.developerfusion.com/article/122498/utentur-sqlbulkcopy-for-high-performance-inserts/


1 commentaires

Merci, je vais regarder à cela, il semble que j'estime une option intéressante, je vais vous donner un test de vérifier combien de temps - sauvegardez-vous des gains sur DataTable, il utilise également DigneAreader VS Dataset ... Je vais y arriver bientôt j'espère (:



0
votes

Si vous ne créez que des données de non-sens, créez une procédure stockée et appelez simplement cela via .NET

Si vous passez des données réelles, la transmettre à nouveau à un processus stocké serait plus rapide, mais vous seriez mieux de laisser tomber la table et de le recréer avec les données.

Si vous insérez une ligne à la fois, il faudra plus de temps que de l'insérer à la fois. Il faudra encore plus longtemps si vous avez des index pour écrire.


0 commentaires

0
votes

Vous pouvez utiliser dapper.net . DAPPER est un micro-orme, exécute une requête et cartographique les résultats dans une liste fortement tapée. Le mappage d'objets-relationnel (ORM, O / RM et O / R Mapping) dans le logiciel informatique est une technique de programmation permettant de convertir des données entre les systèmes de type incompatibles dans les langages de programmation orientés objet. Cela crée, en vigueur, une "base de données d'objet virtuel" qui peut être utilisée à partir de la langue de programmation

Pour plus d'informations:

Consultez https://code.google.com/p/dapper-dot -Net /

Responsentiel GitHub: https://github.com/samsaffron/dapper-dot-net J'espère que cela aide ..


0 commentaires

0
votes

Créer un seul fichier XML pour toutes les lignes que vous souhaitez enregistrer dans la base de données. Passez cette procédure stockée XML sur SQL et enregistrez tous les enregistrements dans un appel uniquement. Mais votre procédure stockée doit être écrite de manière à pouvoir lire tous lire, puis insérer dans la table.


1 commentaires

Je ne pense pas que cela va être plus rapide. De plus, travailler avec XML et les fichiers est beaucoup plus lent que de travailler simplement avec la base de données.




1
votes

Supprimer la boucle ... dans SQL, essayez de faire une table avec 1 million de lignes ... et de rejoindre la jointure qu'il utilise ceci pour insertion / sélectionner des données


0 commentaires

0
votes

Je suis d'accord avec Mike sur SSIS, mais je ne conviens pas que je ne conviens pas votre environnement, cependant pour les processus ETL impliquant des appels de serveurs croisés et des processus de flux de données généraux, il s'agit d'un outil intégré et très intégré.

Avec 1 million de lignes, vous devrez probablement faire un insert en vrac. Selon la taille de la ligne, vous ne seriez pas vraiment en mesure d'utiliser une procédure stockée à moins que vous ne l'iez pas cela en lots. Un jeu de données remplira la mémoire assez rapide, en fonction de la taille de la ligne. Vous pouvez faire une procédure stockée et faire prenez un type de table et appelez-les tous les x nombre de lignes, mais pourquoi ferions-nous cela lorsque vous avez déjà une solution meilleure et plus évolutive. Ce million de rangées pourrait être de 50 millions d'années l'année prochaine.

J'ai un peu utilisé SSIS et si c'est un ajustement organisationnel, je suggérerais de le regarder, mais ce ne serait pas une réponse unique, ne vaudrait pas les dépendances.


0 commentaires