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

Windows Forms Discussion :

temps insertion fichier texte trop long


Sujet :

Windows Forms

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2009
    Messages
    89
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2009
    Messages : 89
    Points : 40
    Points
    40
    Par défaut temps insertion fichier texte trop long
    Bonjour,

    Je développe une application VB avec visual studio qui me permet d'inserer des données brut provenant de fichiers texte dans une BDD sql Server 2005 version express.

    Un répertoire (qui fait en moyenne 2.5 à 3 Mo) represente une semaine et contient à peu pres 80 fichiers textes et chaque fichier contient pas loin de 1000 lignes donc pour une semaine j'insere dans ma table ligneTransaction pas loin de 80 000 lignes.

    Pour chaque ligne j'ai une routine qui la decoupe (avec un split) et je fais des test et des conversion avant d'appeler ma procedure stockée.

    Dans ma procédure stockée je fais un test pour savoir si cette ligne existe, je reupere des clef etrangeres et ensuite je l'insere.

    Quand j'utilise mon application et que je souhaite integrer une semaine le temps d'insertion augmente, pour la premiere semaine je met 6 minutes et quand j'arrive à la quatrième semaine je met pas loin de 41 minutes .

    C'est beaucoup vous ne trouvez pas ? D'autant que dans une année il y a 53 semaine !!!

    Je travaille en local sur un poste windows xp 3.48 Go de ram Pentium Dual Core 2.6 GHz avec visual studio 2008 et sql server 2005 express.

    Est ce que le temps d'execution vous semble normal ?

    Pouvez me donner un tuyau pour diminuer le temps de traitement c'est tres important et ca fait une semaine que je bloque !!

    Merci d'avance !!!

  2. #2
    Membre averti
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    319
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 319
    Points : 414
    Points
    414
    Par défaut
    Bonjour
    Euh non c'est pas long, c'est beaucoup trop long , je sais que je met environ 30sec pour 35k lignes dans ma bdd sous sql server 2005.
    Peut on voir le code qui permet l'insertion dans la bdd?
    Tu fais ca dans un thread a part ou directement dans ton thread principal?
    Cordialement
    Nasty

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2009
    Messages
    89
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2009
    Messages : 89
    Points : 40
    Points
    40
    Par défaut
    je pense que je fais ca dans mon thread principal je ne sais pas trop en fait !!

    Voici mon code je ne sais pas si ca sera lisible c'est la premiere fois que post du code :

    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
    Public Function integrerLigne(ByVal maligne As String, ByVal pointVente As String)
     
            Dim continuLigne As Boolean = True
     
            Dim codeErreur As Int16
            Dim ElementBis() As String = maligne.Split(";")
            Dim v As Char = ","
            Dim p As Char = "."
            Dim sBis As String       
            Dim d1 As DateTime = New DateTime()
            Dim i As Int16
     
            Try
                    If (ElementBis(3).Equals("V") = True) Then
     
                    If (ElementBis(6).Contains(p)) Then
                        sBis = ElementBis(6).Replace(p, v)
                    Else
                        sBis = ElementBis(6)
     
                    End If
     
                    i = CInt(ElementBis(0))
                    Dim d As String = ElementBis(1)
                    Dim h As String = ElementBis(2).Substring(4, 4).Insert(2, ":")
     
     
                    Dim dh As String = d + " " + h
                    d1 = DateTime.Parse(dh)
     
                bd.preparePs("dbo.test")
                bd.addParam("@IdMachine", ParameterDirection.Input, DbType.Int16)
                bd.fixerValeur("@IdMachine", i)
                bd.addParam("@codeUNI", ParameterDirection.Input, DbType.String)
                bd.fixerValeur("@codeUNI", pointVente)
                bd.addParam("@date", ParameterDirection.Input, DbType.DateTime)
                bd.fixerValeur("@date", d1)
                bd.addParam("@decision", ParameterDirection.Input, DbType.String)
                bd.fixerValeur("@decision", ElementBis(3))
                bd.addParam("@codeModePaiement",ParameterDirection.Input,         DbType.String)
                bd.fixerValeur("@codeModePaiement", ElementBis(4))
                bd.addParam("@nbTransaction", ParameterDirection.Input, DbType.Int16)
                    bd.fixerValeur("@nbTransaction", Int16.Parse(ElementBis(5)))
                    bd.addParam("@somme", ParameterDirection.Input, DbType.Decimal)
                    bd.fixerValeur("@somme", Decimal.Parse(sBis))
     
                    codeErreur = bd.executer()
     
                    continuLigne = True
     
                    If (codeErreur = 2) Then
                        continuLigne = False
                    End If
     
     
                End If
     
                Return continuLigne
     
            Catch ex As Exception
                MsgBox("ligne non valide" + bd.getLib + "  " + pointVente + " " + i.ToString + " " + d1.ToString + " " + sBis)
            End Try
     
     
        End Function

  4. #4
    Membre régulier
    Profil pro
    Inscrit en
    Décembre 2009
    Messages
    80
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Décembre 2009
    Messages : 80
    Points : 88
    Points
    88
    Par défaut
    Bonjour,

    Selon moi c'est pas le traitement dans VB pour le split des lignes qui pose problème, ce doit être au niveau SQL que tu as le ralentissement.

    Je pense qu'une procédure stocké a beaucoup d'avantage dans certains cas mais selon mois dans ton cas tu devrait plutôt faire tes inserts avec un Query en direct dans la base. Actuellement la procédure tourne pour chaque ligne.
    Essai d'envoyer plusieurs enregistrement dans la même requete:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    INSERT INTO Table (champ1,champ2,etc...) VALUES (Champ1,champ2,etc)(champ1,champ2,etc)
    Le temps de traitement SQL sera beaucoup plus rapide

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    319
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 319
    Points : 414
    Points
    414
    Par défaut
    C'est une possibilité.
    Pour faire mes insertions massives j'utilise
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    bulk insert elect_test_yln.dbo.FICHE
    from 'C:\Documents and Settings\YLN\fiche.txt'
    with 
    (
    datafiletype = 'widechar',
    fieldterminator = ';',
    rowterminator = '\n',
    firstrow = 1
    );
    tu a juste a faire le traitement dans chacun de tes fichiers pour mettre les "," et autres séparateurs, ce qui doit être gérable niveau code (j'ai pas encore essayé mais ca doit être trouvable)
    Mais je ne promet rien
    Cordialement
    Nasty

  6. #6
    Expert éminent sénior Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 177
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 177
    Points : 25 125
    Points
    25 125
    Par défaut
    executer une requete par ligne c'est ca qui prend du temps

    utilise le bulk insert pour qu'sql server aille directement piocher les données dans les fichiers et ca devrait etre relativement plus instantanné

  7. #7
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2009
    Messages
    89
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2009
    Messages : 89
    Points : 40
    Points
    40
    Par défaut
    Pour bobo :
    Actuellement la procédure tourne pour chaque ligne.
    80000 lignes = 80000 appel de procedure sotckees !!

    Tu me conseille donc d'utiliser un query c ca et non passer par une procedure sotckee ?

    Pour Nasty :

    apres bulk insert tu met quoi le nom de la table ?
    Est ce que je peux utiliser le multithreading si oui tu peux m'en dire plus ?

    Merci beaucoup pour votre aide !!

  8. #8
    Membre averti
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    319
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 319
    Points : 414
    Points
    414
    Par défaut
    Merci Pol63 de confirmer
    Mais ca ne sera toujours pas "instantané", il y aura toujours le temps de traitement pour mettre les fichiers textes en forme et ca peut être assez long des fois! Mais ca sera toujours moins que tes 40minutes
    Cordialement
    Nasty

  9. #9
    Membre régulier
    Profil pro
    Inscrit en
    Décembre 2009
    Messages
    80
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Décembre 2009
    Messages : 80
    Points : 88
    Points
    88
    Par défaut
    bulk je ne connais pas, je peux pas me prononcer.
    Cependant j'avais fait des tests en executant un executenonquery avec mes requetes en "string" dans une boucle ou je splittait environ par 100 insertions par requete et les temps d'execution se sont environ divisé par 10

  10. #10
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2009
    Messages
    89
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2009
    Messages : 89
    Points : 40
    Points
    40
    Par défaut
    Je n'ai jamais utilise bulk !!
    C'est une requete sql ? ou une fonction VB ?

    Le probleme c'est qu'il faut renseigner le chemin du fichier et que dans mon cas le fichier est un parametre car j'en ai plusieurs dans plusieurs repertoire !!

    Merci d'avance !!

  11. #11
    Membre averti
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    319
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 319
    Points : 414
    Points
    414
    Par défaut
    bulk insert c'est du sql.
    il faut passer le chemin du fichier a traiter.
    Si tu veux te faciliter le travail, il est envisageable de regrouper tous les fichiers de ton dossier dans un seul fichier texte (et faire la mise en forme par la même occasion), de lui attribuer un nom précis et tu passe le chemin de ce fichier en tant que paramètre.
    Je ne l'ai pas fait via vb, mais ca doit être faisable!

    p.s et edit : pour le multithread je ne suis pas un expert mais je vais essayer de m'expliquer
    tu as un thread A qui va faire le traitement des fichiers du dossier 1, quand c'est fini l'insertion se fait dans un thread B et pendant l'insertion ton thread A va faire le traitement des fichiers du dossier 2 et ainsi de suite.
    Je suis sur que tu peux gagner de precieuses minutes (voir heure vue la durée de tes traitements ) en la jouant comme ca. Mais je peux pas t'expliquer plus j'ai encore un peu de mal avec le multithread

    Cordialement
    Nasty

  12. #12
    Expert éminent sénior Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 177
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 177
    Points : 25 125
    Points
    25 125
    Par défaut
    tu peux aussi tenter autre chose
    si tous tes fichiers vont dans la meme table
    tu ouvres tous les fichiers
    tu utilises un system.text.stringbuilder pour concaténer toutes tes requetes
    et dans le commandtext tu mets le contenu du stringbuilder
    il n'y aura donc qu'une requete qui va passer

    il parrait meme que plutot que
    insert into
    insert into
    ...
    il serait plus rapide de faire
    insert into
    select ..
    union select ..
    union select ..

  13. #13
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2009
    Messages
    89
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2009
    Messages : 89
    Points : 40
    Points
    40
    Par défaut
    Merci pour toutes ces reponses je vais tenter le bulk !

    j'ai donc crée une procedure stockee et je passe le chemin du fichier en parametre mais ca ne marche pas :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    create proc insererFichier  @cheminfichier varchar(300)
     
    as
    begin
    		BULK INSERT ligne
    		FROM @cheminfichier 
    		WITH (FIELDTERMINATOR = '\n', ROWTERMINATOR = ';')
     
    end

  14. #14
    Membre averti
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    319
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 319
    Points : 414
    Points
    414
    Par défaut
    Bonjour
    Pourquoi passer par une procédure stockée?
    Si tu travaille en VB tu peux tres bien faire la requête depuis ton code!
    Et pour l'instant tu as quoi comme erreur lors de l'execution?
    Cordialement
    Nasty

  15. #15
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2009
    Messages
    89
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2009
    Messages : 89
    Points : 40
    Points
    40
    Par défaut
    Bonjour,

    Voici les erreurs :

    Msg*102, Niveau*15, État*1, Procédure*insererFichier, Ligne*7
    Syntaxe incorrecte vers '@cheminfichier'.
    Msg*319, Niveau*15, État*1, Procédure*insererFichier, Ligne*8
    Syntaxe incorrecte près du mot clé «*with*». Si l'instruction est une expression de table commune ou une clause xmlnamespaces, l'instruction précédente doit se terminer par un point-virgule.
    Merci

  16. #16
    Membre averti
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    319
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 319
    Points : 414
    Points
    414
    Par défaut
    Re bonjour
    Euh pour la première erreur, as tu pensé a mettre les " ' " autour de ton chemin?
    Et pour la deuxième j'ai pas encore d'idée.
    Cordialement
    Nasty

  17. #17
    Expert éminent sénior Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 177
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 177
    Points : 25 125
    Points
    25 125
    Par défaut
    à mon avis c'est plutot que bulk insert veut le chemin directement, pas dans une variable
    donc là aussi executer le bulk insert dans le commandtext plutot que de passer par une procédure stockée serait plus conseillé
    ca permet de concaténer le chemin dans la requete

  18. #18
    Membre averti
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    319
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 319
    Points : 414
    Points
    414
    Par défaut
    Je ne savais pas que lorsque l'on donnait un chemin via une variable il n'etait pas nécessaire d'ajouter les '!
    Cordialement
    Nasty

  19. #19
    Expert éminent sénior Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 177
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 177
    Points : 25 125
    Points
    25 125
    Par défaut
    un string en vb.net que tu mets dans une variable tu fais monstring = "valeur"
    mais il contient valeur seulement
    en sql quand on appelle une procédure stockée qui demande un varchar soit on fait une variable
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    declare @str varchar(50)
    set @str = 'test' -- qui ne contient donc pas de '
    exec sp @str
    ou alors directement
    le ' n'est qu'un délimiteur

  20. #20
    Membre averti
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    319
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 319
    Points : 414
    Points
    414
    Par défaut
    Oui c'est logique, je te remercie pour ce micro cours!
    Cordialement
    Nasty

Discussions similaires

  1. [VB6]Message d'erreur si le temps d'exécution est trop long
    Par Asdorve dans le forum VB 6 et antérieur
    Réponses: 16
    Dernier message: 14/09/2006, 17h43
  2. Réponses: 2
    Dernier message: 29/08/2006, 17h18
  3. textbox et onKeyUp event -> largeur augmente auto quand texte trop long
    Par Miketrix dans le forum Général JavaScript
    Réponses: 7
    Dernier message: 25/07/2006, 12h14
  4. [FLASH8] Insertion fichier texte et fleches
    Par BrItneY dans le forum Flash
    Réponses: 8
    Dernier message: 27/06/2006, 14h46
  5. Fichier texte trop gros pour etre ouvert
    Par tavman dans le forum C++
    Réponses: 5
    Dernier message: 05/10/2005, 01h07

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