C# en parallèle de multiples insertions dans la base de données
J'ai un datatable avec environ 3000 lignes. Chacune de ces lignes doivent être insérées dans une table de base de données. Actuellement, je suis en cours d'exécution d'une boucle foreach:
obj_AseCommand.CommandText = sql_proc;
obj_AseCommand.CommandType = CommandType.StoredProcedure;
obj_AseCommand.Connection = db_Conn;
obj_AseCommand.Connection.Open();
foreach (DataRow dr in dt.Rows)
{
obj_AseCommand.Parameters.AddWithValue("@a", dr["a"]);
obj_AseCommand.Parameters.AddWithValue("@b", dr["b"]);
obj_AseCommand.Parameters.AddWithValue("@c", dr["c"]);
obj_AseCommand.ExecuteNonQuery();
obj_AseCommand.Parameters.Clear();
}
obj_AseCommand.Connection.Close();
Pouvez-vous me conseiller comment puis-je faire en parallèle exécuter la SP dans la base de données depuis l'approche ci-dessus prend environ 10 minutes pour insérer 3000 lignes.
Juste par curiosité: pourquoi êtes - vous l'ajout de 3000 lignes de la base de données avec une procédure stockée? si c'est à partir de certains des fichiers d'entrée, pourquoi ne pas l'importer directement dans la base de données avec quelques outil de gestion?
La datatable est rempli à partir d'une autre base de données une base de données master. Mon but est de récupérer des données à partir de la base de données master et insérez le dans ma base de données.La procédure stockée est utilisée pour insérer des données dans ma base de données.
Pourquoi ne pas faire usage de l'insertion en bloc, ou un lien de serveur, et le SQL fetch et insérer les données
Difficile, je pense que c'est beaucoup mieux de le faire avec bulk insert / import / quel que soit votre SGBD appelle. Il vous permettra d'économiser beaucoup de peine et le temps.
La datatable est rempli à partir d'une autre base de données une base de données master. Mon but est de récupérer des données à partir de la base de données master et insérez le dans ma base de données.La procédure stockée est utilisée pour insérer des données dans ma base de données.
Pourquoi ne pas faire usage de l'insertion en bloc, ou un lien de serveur, et le SQL fetch et insérer les données
Difficile, je pense que c'est beaucoup mieux de le faire avec bulk insert / import / quel que soit votre SGBD appelle. Il vous permettra d'économiser beaucoup de peine et le temps.
OriginalL'auteur Harsh | 2015-01-05
Vous devez vous connecter pour publier un commentaire.
Modifier
Avec le recul, à l'aide d'un
Parallel.ForEach
pour paralléliser DB insertions est un peu inutile, car il va consommer un thread pour chaque Connexion. Sans doute, une meilleure parallèle solution serait d'utiliser les versions asynchrones de laSystem.Data
Db Opérations, telles que ExecuteNonQueryAsync , de démarrer les exécutions (simultanément), et ensuite utiliserawait Task.WhenAll()
attendre la fin - cela permettra d'éviter le Fil généraux de l'appelant, bien que l'ensemble de la Db de rendement ne sera probablement pas tous rapide. Plus iciRéponse originale à cette question, en Parallèle de multiples Insertions dans la Base de données
Vous pouvez le faire en parallèle à l'aide de TPL, par exemple, plus précisément avec la
localInit
surcharge de En parallèle.ForEach. Vous aurez presque certainement envie de regarder la limitation de la quantité de parallélisme en peaufinant MaxDegreeOfParalelism afin de ne pas inonder votre base de données:Notes:
.Prepare()
si vous utilisez Sql ad Hoc ou Sql versions antérieures à 2005DataTable's
lignes est thread-safe. Vous aurez envie de vérifier, bien sûr.Note De Côté:
10 minutes de 3000 lignes est excessif, même avec une grande table et un seul thread. Qu'est-ce que votre proc? J'ai supposé que le traitement n'est pas trivial, d'où la nécessité pour la procédure stockée, mais si vous êtes juste en faisant de simples insère, comme par @3dd commentaire, SqlBulkCopy donnera des inserts ~ 1M de lignes par minute sur un raisonnablement table étroite.
Il y a quelque chose de très étrange se passe avec votre SGBDR si même un BulkCopy prend 10 minutes pour 3000 lignes. Je devine que vous avez des déclencheurs sur la table inserted qui font beaucoup de logique, ou il y a beaucoup de conflit de verrouillage, ou peut-être que vous avez beaucoup de contraintes, des règles, des index et de la table est extrêmement large. Vous aurez besoin d'un DBA pour avoir un regard sérieux à la table de l'insertion des technologies et de l'absence de parallélisme ne sont pas le goulot d'étranglement ici 🙁
OriginalL'auteur StuartLC
il est préférable de passer l'ensemble des données de la table dans la base de données
dans la base de données, vous devez créer type de table qui correspondent exactement avec les données de la table
dans le magasin de la procédure que vous pouvez faire quelque chose comme ça...
OriginalL'auteur Dhaval
Vous pouvez utiliser
SqlBulkCopy
. Voir l'exemple de code ci-dessous. LeWriteToServer
méthode, écrit Ledatatable
à la base de données, à condition qu'ils soient de la même cartographieOriginalL'auteur mayowa ogundele
Vous pouvez utiliser SqlBulkCopy
guide est ici
Ok désolé, je suis un nouvel utilisateur 🙂
C'est une réponse valable (bien que peut-être pas une bonne réponse), il pourrait être amélioré par l'ajout de quelques explications du pourquoi et du comment.
OriginalL'auteur Mehmet Otkun