Bonjour,
Nous développons un module de synchronisation qui alimente notre base de données à partir des données fournies par un prestataire.
Dans un premier temps, nous créons une copie de la base de données du prestataire, via des appels à ses webservices.
Dans un deuxième temps, nous faisons un transformation ETL entre la base "prestataire" et notre base de données.
Actuellement, les 2 opérations sont très longues. Ces mauvaises performances s'expliquent en partie par le fait que les requêtes d'insertion/mises à jour sont exécutées individuellement...
Par exemple, pour remplir une des tables de la base "prestataire", nous utilisons la méthode suivante :
Cette méthode est donc appelé pour chaque ligne de cette table "group_team". Je souhaiterais à la place utilisée de l'insertion multiple.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43 public void updateGroupTeam(bool isGroup, int id, int club_id) { using (NpgsqlConnection c = (NpgsqlConnection)conn.getConnexion()) { using (NpgsqlCommand command = new NpgsqlCommand()) { c.Open(); command.Connection = c; command.Parameters.Clear(); int n = -1; // update, sinon insertion command.CommandText = " UPDATE group_team SET id=id WHERE team_id=:team_id AND group_id = :group_id "; command.Parameters.Add(new NpgsqlParameter("group_id", DbType.Int64)).Value = (long)id; command.Parameters.Add(new NpgsqlParameter("team_id", DbType.Int64)).Value = (long)club_id; try { n = command.ExecuteNonQuery(); } catch (Exception e) { log.Error("updateGroupTeam() UPDATE : " + e.Message); } if (n <= 0) { // insertion command.CommandText = " INSERT INTO group_team( team_id, group_id) VALUES ( :team_id, :group_id);"; command.Parameters.Clear(); command.Parameters.Add(new NpgsqlParameter("group_id", DbType.Int64)).Value = (long)id; command.Parameters.Add(new NpgsqlParameter("team_id", DbType.Int64)).Value = (long)club_id; try { n = command.ExecuteNonQuery(); } catch (Exception e) { log.Error("updateGroupTeam() INSERT : " + e.Message); } } } } }
Pour cela, j'hésite entre :
- utiliser des transactions
- créer une requête qui contient toutes les lignes à insérer, afin d'utiliser une seule "Connection".
Je suis en train de faire des tests en utilisant la deuxième méthode : une requête contenant toutes les lignes à insérer.
Je me demande cependant comment gérer à la fois l'update et l'insert? En effet, avec la méthode actuelle, on sait que si une ligne ne peut pas être updatée, c'est qu'elle doit être insérée. Mais comemnt gérer ce cas dans le cas d'une insertion multiple?
- dois je d'abord faire un update sur l'ensemble des lignes, puis un insert de l'ensemble des lignes?
- peut on récupérer les lignes "posant problème" sans interrompre le traitement du reste des lignes?
Merci d'avance,
Partager