IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

VB.NET Discussion :

Ecriture de données en masse


Sujet :

VB.NET

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Inscrit en
    Avril 2010
    Messages
    47
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2010
    Messages : 47
    Points : 38
    Points
    38
    Par défaut Ecriture de données en masse
    Bonjour,

    Je ne sais pas bien si c'est ici que je dois poster ma question mais on déplacera si nécessaires.

    Je précise que je continue mes recherches en parallèles de ce poste bien sur !

    Voici mon problème,

    J'ai un programme qui va lire des informations dans une base Oracle sur un site distant et qui va ensuite écrire toutes les lignes trouvées dans la base Mysql de mon serveur Local.

    Le soucis est que j'ai par exemple 37.000 lignes à écrire ... et que ça prend un temps certains ...

    Pour écrire mes informations j'utilise une programme que j'aie développé en VB.net et dans lequel je charge un DataReader avec les informations trouvées et lance une boucle Do While pour ecrire les informations.

    Existe t-il une solution plus rapide ou moins usine à gaz pour rapatrier les informations ???

    Voici le code en question.

    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
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
     Dim CmdOracle As New OracleCommand(TextSql, DBOracle1)
                    DrORacle = CmdOracle.ExecuteReader
     
                    If DrORacle.HasRows Then
     
                        Do While DrORacle.Read
     
                            Enseigne = DrORacle.GetString(0).ToString
                            Saison = DrORacle.GetString(1).ToString
                            Nom = DrORacle.GetString(2).ToString
                            NumCommande = DrORacle.GetString(3).ToString
                            Buyer = DrORacle.GetString(4).ToString
                            Famille = DrORacle.GetString(5).ToString
                            Coloris = DrORacle.GetString(6).ToString
     
                            If Not DrORacle.IsDBNull(7) Then
                                LibColoris = Strings.Replace(DrORacle.GetString(7).ToString, "'", "''")
                            Else
                                LibColoris = "N/A"
                            End If
     
                            If Not DrORacle.IsDBNull(8) Then
                                CodeGrilleTaille = DrORacle.GetInt32(8)
                            Else
                                CodeGrilleTaille = 0
                            End If
     
                            If Not DrORacle.IsDBNull(9) Then
                                LibGrilleTaille = DrORacle.GetString(9).ToString
                            Else
                                LibGrilleTaille = "N/A"
                            End If
     
                            Fournisseur = Strings.Replace(DrORacle.GetString(10).ToString, "'", "''")
                            OTB = Strings.Replace(DrORacle.GetString(11).ToString, "'", "''")
                            Themes = Strings.Replace(DrORacle.GetString(12).ToString, "'", "''")
     
                            If Not DrORacle.IsDBNull(13) Then
                                DistriProd = Strings.Replace(DrORacle.GetString(13).ToString, "'", "''")
                            Else
                                DistriProd = "N/A"
                            End If
     
                            PlieSup = DrORacle.GetString(14).ToString
                            MEPREA = DrORacle.GetString(15).ToString
     
                            Paht = DrORacle.GetDecimal(16)
                            QttCommande = DrORacle.GetInt32(17)
                            QttLivre = DrORacle.GetInt32(18)
                            QttResteALivre = DrORacle.GetInt32(19)
     
                            Dim Jour, Mois, Annee As String
     
                            Jour = "00" & DrORacle.GetOracleDate(20).Day.ToString
                            Mois = "00" & DrORacle.GetOracleDate(20).Month.ToString
                            Annee = DrORacle.GetOracleDate(20).Year.ToString
     
                            DateLivraison = Annee & "-" & Strings.Right(Mois, 2) & "-" & Strings.Right(Jour, 2)
     
                            If Not DrORacle.IsDBNull(21) Then
                                Jour = "00" & DrORacle.GetOracleDate(21).Day.ToString
                                Mois = "00" & DrORacle.GetOracleDate(21).Month.ToString
                                Annee = DrORacle.GetOracleDate(21).Year.ToString
                                DDM = Annee & "-" & Strings.Right(Mois, 2) & "-" & Strings.Right(Jour, 2)
                            Else
                                DDM = "1900-01-01"
                            End If
     
                            If Not DrORacle.IsDBNull(22) Then
                                Jour = "00" & DrORacle.GetOracleDate(22).Day.ToString
                                Mois = "00" & DrORacle.GetOracleDate(22).Month.ToString
                                Annee = DrORacle.GetOracleDate(22).Year.ToString
                                DateDIM = Annee & "-" & Strings.Right(Mois, 2) & "-" & Strings.Right(Jour, 2)
                            Else
                                DateDIM = "2050-12-31"
                            End If
     
                            If Not DrORacle.IsDBNull(23) Then
                                RefFourn = Strings.Replace(DrORacle.GetString(23).ToString, "'", "''")
                            Else
                                RefFourn = "N/A"
                            End If
     
                            If Not DrORacle.IsDBNull(24) Then
                                Stagged = Strings.Replace(DrORacle.GetString(24).ToString, "'", "''")
                            Else
                                Stagged = "N/A"
                            End If
     
                            If Not DrORacle.IsDBNull(25) Then
                                Ironing = Strings.Replace(DrORacle.GetString(25).ToString, "'", "''")
                            Else
                                Ironing = "N/A"
                            End If
     
                            If Not DrORacle.IsDBNull(26) Then
                                OnHanger = Strings.Replace(DrORacle.GetString(26).ToString, "'", "''")
                            Else
                                OnHanger = "N/A"
                            End If
     
                            TextSql = "insert into gat (enseigne, saison, nom, commande, buyer, famille, coloris, libcoloris, codegrilletaille, libgrilletaille, fournisseur, otb, themes, paht, qttcommande, qttlivre, qtereste, datelivraison, ddm, dim, pliesup, meprea, distriprod, reffourn, stagged, ironing, onhanger ) values ('" & Enseigne & "', '" & Saison & "', '" & Nom & "', " & NumCommande & ", '" & Buyer & "', '" & Famille & "', '" & Coloris & "', '" & LibColoris & "', " & CodeGrilleTaille & ", '" & LibGrilleTaille & "', '" & Fournisseur & "', '" & OTB & "', '" & Themes & "', '" & Paht & "', " & QttCommande & ", " & QttLivre & ", " & QttResteALivre & ", '" & DateLivraison & "', '" & DDM & "', '" & DateDIM & "', '" & PlieSup & "', '" & MEPREA & "', '" & DistriProd & "', '" & RefFourn & "', '" & Stagged & "', '" & Ironing & "', '" & OnHanger & "')"
     
                            Dim CmdTraitement As New MySqlCommand(TextSql, DBMysql5)
                            CmdTraitement.ExecuteNonQuery()
     
                        Loop
     
                    End If
     
                    DrORacle.Close()
    Merci d'avance à tous pour vos idées d'amélioration !

  2. #2
    Expert confirmé Avatar de ed73170
    Homme Profil pro
    Développeur indépendant
    Inscrit en
    Mai 2009
    Messages
    765
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur indépendant

    Informations forums :
    Inscription : Mai 2009
    Messages : 765
    Points : 5 522
    Points
    5 522
    Par défaut
    Bonjour,

    Si c'est le temps d'insertion qui est long, tu peux peut-être essayer d'écrire tes lignes dans un fichier texte sur ton serveur puis de le charger dans MySQL par LOAD DATA INFILE.

    Voir ici : http://dev.mysql.com/doc/refman/4.1/en/load-data.html

  3. #3
    Modérateur
    Avatar de DotNetMatt
    Homme Profil pro
    CTO
    Inscrit en
    Février 2010
    Messages
    3 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : CTO
    Secteur : Finance

    Informations forums :
    Inscription : Février 2010
    Messages : 3 611
    Points : 9 743
    Points
    9 743
    Billets dans le blog
    3
    Par défaut
    37000 lignes c'est pas non plus énorme. Pour accélérer les insertions en masse, on peut :
    - Supprimer les index avant l'insertion, puis les recréer une fois que c'est terminé.
    - Gérer toutes les instructions insert au sein d'une seule et unique transaction.

    Donc tu peux tester ces 2 points et voir si cela améliore les choses ou non...
    Less Is More
    Pensez à utiliser les boutons , et les balises code
    Desole pour l'absence d'accents, clavier US oblige
    Celui qui pense qu'un professionnel coute cher n'a aucune idee de ce que peut lui couter un incompetent.

  4. #4
    Nouveau membre du Club
    Homme Profil pro
    Inscrit en
    Avril 2010
    Messages
    47
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2010
    Messages : 47
    Points : 38
    Points
    38
    Par défaut
    Bonjour DotNetMatt,

    Je suis d'accord 37.000 lignes ce n'est pas grand choses mais bon 9 minutes c'est long ...
    Je vais réécrire ces informations mise à jours toute les nuit avec un automate que j'ai programmé.

    Qu'est-ce que tu entend par gérer toutes les instructions insert au sein d'une seule et unique transaction ?

    et supprimer les index, je fait un truncate de la table au début de chaque nouvelle écriture.

  5. #5
    Modérateur
    Avatar de DotNetMatt
    Homme Profil pro
    CTO
    Inscrit en
    Février 2010
    Messages
    3 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : CTO
    Secteur : Finance

    Informations forums :
    Inscription : Février 2010
    Messages : 3 611
    Points : 9 743
    Points
    9 743
    Billets dans le blog
    3
    Par défaut
    Citation Envoyé par 0n31l Voir le message
    Je suis d'accord 37.000 lignes ce n'est pas grand choses mais bon 9 minutes c'est long ...
    Ah oui, 9 minutes pour 37000 lignes c'est même très très long

    Citation Envoyé par 0n31l Voir le message
    Qu'est-ce que tu entend par gérer toutes les instructions insert au sein d'une seule et unique transaction ?
    Dans le code que tu as posté plus haut, on voit qu'à chaque fois que tu lis une ligne, tu génères une commande INSERT puis tu l'envoie au serveur (ExecuteNonQuery).

    C'est probablement cela qui cause autant de latence. Je pense que tu devrais "bufferiser" tes instructions INSERT, puis toutes les soumettre en même temps au serveur, ce serait beaucoup plus efficace. Voici un exemple de code en me basant sur le tiens :
    Code VB.NET : 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
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
     Dim CmdOracle As New OracleCommand(TextSql, DBOracle1)
     Dim inserts As New StringBuilder()
     
    DrORacle = CmdOracle.ExecuteReader
     
    If DrORacle.HasRows Then
     
    	Do While DrORacle.Read
     
    		Enseigne = DrORacle.GetString(0).ToString
    		Saison = DrORacle.GetString(1).ToString
    		Nom = DrORacle.GetString(2).ToString
    		NumCommande = DrORacle.GetString(3).ToString
    		Buyer = DrORacle.GetString(4).ToString
    		Famille = DrORacle.GetString(5).ToString
    		Coloris = DrORacle.GetString(6).ToString
     
    		If Not DrORacle.IsDBNull(7) Then
    			LibColoris = Strings.Replace(DrORacle.GetString(7).ToString, "'", "''")
    		Else
    			LibColoris = "N/A"
    		End If
     
    		If Not DrORacle.IsDBNull(8) Then
    			CodeGrilleTaille = DrORacle.GetInt32(8)
    		Else
    			CodeGrilleTaille = 0
    		End If
     
    		If Not DrORacle.IsDBNull(9) Then
    			LibGrilleTaille = DrORacle.GetString(9).ToString
    		Else
    			LibGrilleTaille = "N/A"
    		End If
     
    		Fournisseur = Strings.Replace(DrORacle.GetString(10).ToString, "'", "''")
    		OTB = Strings.Replace(DrORacle.GetString(11).ToString, "'", "''")
    		Themes = Strings.Replace(DrORacle.GetString(12).ToString, "'", "''")
     
    		If Not DrORacle.IsDBNull(13) Then
    			DistriProd = Strings.Replace(DrORacle.GetString(13).ToString, "'", "''")
    		Else
    			DistriProd = "N/A"
    		End If
     
    		PlieSup = DrORacle.GetString(14).ToString
    		MEPREA = DrORacle.GetString(15).ToString
     
    		Paht = DrORacle.GetDecimal(16)
    		QttCommande = DrORacle.GetInt32(17)
    		QttLivre = DrORacle.GetInt32(18)
    		QttResteALivre = DrORacle.GetInt32(19)
     
    		Dim Jour, Mois, Annee As String
     
    		Jour = "00" & DrORacle.GetOracleDate(20).Day.ToString
    		Mois = "00" & DrORacle.GetOracleDate(20).Month.ToString
    		Annee = DrORacle.GetOracleDate(20).Year.ToString
     
    		DateLivraison = Annee & "-" & Strings.Right(Mois, 2) & "-" & Strings.Right(Jour, 2)
     
    		If Not DrORacle.IsDBNull(21) Then
    			Jour = "00" & DrORacle.GetOracleDate(21).Day.ToString
    			Mois = "00" & DrORacle.GetOracleDate(21).Month.ToString
    			Annee = DrORacle.GetOracleDate(21).Year.ToString
    			DDM = Annee & "-" & Strings.Right(Mois, 2) & "-" & Strings.Right(Jour, 2)
    		Else
    			DDM = "1900-01-01"
    		End If
     
    		If Not DrORacle.IsDBNull(22) Then
    			Jour = "00" & DrORacle.GetOracleDate(22).Day.ToString
    			Mois = "00" & DrORacle.GetOracleDate(22).Month.ToString
    			Annee = DrORacle.GetOracleDate(22).Year.ToString
    			DateDIM = Annee & "-" & Strings.Right(Mois, 2) & "-" & Strings.Right(Jour, 2)
    		Else
    			DateDIM = "2050-12-31"
    		End If
     
    		If Not DrORacle.IsDBNull(23) Then
    			RefFourn = Strings.Replace(DrORacle.GetString(23).ToString, "'", "''")
    		Else
    			RefFourn = "N/A"
    		End If
     
    		If Not DrORacle.IsDBNull(24) Then
    			Stagged = Strings.Replace(DrORacle.GetString(24).ToString, "'", "''")
    		Else
    			Stagged = "N/A"
    		End If
     
    		If Not DrORacle.IsDBNull(25) Then
    			Ironing = Strings.Replace(DrORacle.GetString(25).ToString, "'", "''")
    		Else
    			Ironing = "N/A"
    		End If
     
    		If Not DrORacle.IsDBNull(26) Then
    			OnHanger = Strings.Replace(DrORacle.GetString(26).ToString, "'", "''")
    		Else
    			OnHanger = "N/A"
    		End If
     
    		inserts.Append("insert into gat (enseigne, saison, nom, commande, buyer, famille, coloris, libcoloris, codegrilletaille, libgrilletaille, fournisseur, otb, themes, paht, qttcommande, qttlivre, qtereste, datelivraison, ddm, dim, pliesup, meprea, distriprod, reffourn, stagged, ironing, onhanger ) values ('" & Enseigne & "', '" & Saison & "', '" & Nom & "', " & NumCommande & ", '" & Buyer & "', '" & Famille & "', '" & Coloris & "', '" & LibColoris & "', " & CodeGrilleTaille & ", '" & LibGrilleTaille & "', '" & Fournisseur & "', '" & OTB & "', '" & Themes & "', '" & Paht & "', " & QttCommande & ", " & QttLivre & ", " & QttResteALivre & ", '" & DateLivraison & "', '" & DDM & "', '" & DateDIM & "', '" & PlieSup & "', '" & MEPREA & "', '" & DistriProd & "', '" & RefFourn & "', '" & Stagged & "', '" & Ironing & "', '" & OnHanger & "');" & VbCrLf) ' Note: j'ai ajouté le point virgule à la fin pour séparer les instructions
     
    	Loop
     
    	TextSql = inserts.ToString()
     
    	Dim CmdTraitement As New MySqlCommand(TextSql, DBMysql5)
    	CmdTraitement.ExecuteNonQuery()
     
    End If
     
    DrORacle.Close()
    Teste avec ca et dis-nous ce que ca donne (peut-être quelques ajustements de syntaxe à faire car ca fait longtemps que je n'ai pas codé en VB.NET )

    Autre point important, utilise des requêtes paramétrées : .Net, SQL Server, et les requêtes paramétrées (VB.Net) (sous Oracle le principe reste le même, seule la syntaxe change : il ne faut pas utiliser "@" devant un paramètre mais ":").
    Less Is More
    Pensez à utiliser les boutons , et les balises code
    Desole pour l'absence d'accents, clavier US oblige
    Celui qui pense qu'un professionnel coute cher n'a aucune idee de ce que peut lui couter un incompetent.

  6. #6
    Membre éprouvé Avatar de worm83
    Homme Profil pro
    Architecte logiciel
    Inscrit en
    Février 2010
    Messages
    459
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Architecte logiciel
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2010
    Messages : 459
    Points : 1 118
    Points
    1 118
    Par défaut
    Bonjour,

    Pour une importante insertion en BDD (plusieurs centaines de méga voir Giga), je ne peux te recommander que de regarder le "BulkInsert".
    Il est vrai que 37K enregistrements n'est pas énorme, tu pourrais au lieu d’insérer ligne par ligne, de créer une requête qui concatène l'ensemble des données d'un seul coup comme te le conseil DotNetMatt.
    "Le train de tes injures roule sur le rail de mon indifférence."

    "Monde de merde !!"

    Georges Abitbol.

  7. #7
    Membre confirmé
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Août 2014
    Messages
    218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Août 2014
    Messages : 218
    Points : 493
    Points
    493
    Par défaut
    Bonjour

    Deux choses :

    - sans modification majeures, ça irait beaucoup plus vite si les inserts étaient fait dans une transaction unique. Ici on utilise une transaction implicite et c'est la seule et unique raison de ce temps de traitement absurde.

    - je ne comprends pas trop l’intérêt de faire un programme applicatif pour faire du DB => DB. il y a des outils pour cela (ici SSIS ferait très bien le taf).
    Beaucoup trop d'hommes viennent au monde : l'Etat a été inventé pour ceux qui sont superflus. (Friedrich Nietzsche)

Discussions similaires

  1. [VBA-E]Ecriture de données dans un fichier texte
    Par osito57 dans le forum Macros et VBA Excel
    Réponses: 15
    Dernier message: 18/08/2017, 19h42
  2. Ecriture des données d'une table dans un fichier
    Par jeunot0108 dans le forum Forms
    Réponses: 3
    Dernier message: 13/08/2007, 12h49
  3. ecriture de données sur le port série
    Par sanatou dans le forum Windows
    Réponses: 2
    Dernier message: 20/12/2006, 18h09
  4. [CSV] Ecriture des données dans un fichier
    Par kagura dans le forum Langage
    Réponses: 3
    Dernier message: 07/11/2006, 22h55

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo