Performances de SqlBulkCopy

c# sqlbulkcopy sql-server

Question

Je travaille pour augmenter la performance des charges en vrac; Des centaines de millions d'enregistrements + quotidiennement.

J'ai alors décidé d'utiliser l'interface IDatareader à la place des tables de données et d'améliorer considérablement les performances (500 000 enregistrements de plus par minute). La configuration actuelle est:

  • Un lecteur personnalisé mis en cache pour analyser les fichiers délimités.
  • Envelopper le lecteur de flux dans un flux en mémoire tampon.
  • Une classe de lecture d'objet personnalisée qui énumère les objets et implémente l'interface IDatareader .
  • Ensuite, SqlBulkCopy écrit sur le serveur

Le gros du goulot de la bouteille de performance se trouve directement dans SqlBulkCopy.WriteToServer . Si je teste le processus jusqu’à l’exclusion du WriteToServer mais en excluant celui- WriteToServer le processus retourne dans environ une minute. WriteToServer prend plus de 15 minutes supplémentaires. Pour le test unitaire, il se trouve sur mon ordinateur local, de sorte que le même disque que celui sur lequel repose la base de données évite de copier les données sur le réseau.

J'utilise une table de segment de mémoire (pas d'index; en cluster ou non; j'ai joué avec différentes tailles de lot sans différences majeures de performances).

Il est nécessaire de réduire les temps de chargement, j'espère donc que quelqu'un pourrait maintenant trouver un moyen d'extraire un peu plus de sang de ce retournement.

Réponse acceptée

Pourquoi ne pas utiliser directement SSIS?

Quoi qu'il en soit, si vous avez essayé d'analyser IDataReader, vous êtes déjà sur le bon chemin. Pour optimiser SqlBulkCopy lui-même, vous devez vous concentrer sur SQL Server. La clé est les opérations journalisées au minimum. Vous devez lire ces articles MSDN:

Si votre cible est un arbre B (c'est-à-dire une table indexée en cluster), malheureusement, l'un des principes les plus importants d'insertion en bloc performant, à savoir l'ensemble de lignes d'entrée triée, ne peut pas être déclaré. En résumé, ADO.Net SqlClient n'a pas l'équivalent de SSPROP_FASTLOADOPTIONS -> ORDER(Column) (OleDb). Comme le moteur ne sait pas que les données sont déjà triées, un opérateur de tri est ajouté au plan, ce qui n’est pas si grave, sauf lorsqu’il se renverse. Pour éviter les déversements, utilisez une petite taille de lot (~ 10 000). Voir mon point de départ: toutes ces options ne sont que des clics à définir dans SSIS plutôt que de chercher dans les spécifications MSDN OleDB ...

Si votre flux de données n'est pas trié pour commencer ou si la destination est un tas, mon point ci-dessus est muet.

Cependant, la journalisation minimale reste indispensable pour des performances décentes.



Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi