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 :

Remplir Datagrid depuis bdd SQL Serveur avec indicateur de vitesse


Sujet :

VB.NET

  1. #1
    Futur Membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Août 2011
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2011
    Messages : 11
    Points : 7
    Points
    7
    Par défaut Remplir Datagrid depuis bdd SQL Serveur avec indicateur de vitesse
    Bonsoir,

    J'ai une appli tournant sous vb.net 2.0, elle fonctionne très bien, j'aurais juste besoin d'une petite amélioration. Elle s'occupe de remplir un datagrid depuis une table sql server 2005. Les records de cette table peuvent être supérieur à 100 000 lignes sur 25 colonnes, c'est pourquoi l'opération peut être longue.
    J'aurais aimé un moyen d'indiquer par exemple le nombre de lignes effectuées, ou le temps de restant, ou autre, du moins arriver à montrer aux clients l'avancement.

    Voici mon code actuel :
    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
     
    Private Sub ShowInDatagrid()
     
            Dim con As New System.Data.SqlClient.SqlConnection
            con.ConnectionString = logbdd
     
            Dim cmd As System.Data.SqlClient.SqlCommand
     
            Dim myDA As System.Data.SqlClient.SqlDataAdapter
     
            Dim myDataSet As System.Data.DataSet
     
            'Binding database table to DataGridView
     
            cmd = New System.Data.SqlClient.SqlCommand("Select * FROM T_Matable", con)
     
            If con.State = System.Data.ConnectionState.Closed Then con.Open()
     
            myDA = New System.Data.SqlClient.SqlDataAdapter(cmd)
     
            myDataSet = New System.Data.DataSet()
     
            myDA.Fill(myDataSet, "T_Matable")
     
            DataGridView1.DataSource = myDataSet.Tables("T_Matable").DefaultView
     
        End Sub

    Merci d'avance.

  2. #2
    Modérateur
    Avatar de Sankasssss
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2006
    Messages
    1 842
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 842
    Points : 4 232
    Points
    4 232
    Par défaut
    Bonjour,

    une méthode vraiment barbare consisterait à utiliser un datareader au lieu du remplissage par dataAdapteur.
    Tu pourrais recréer l'ensemble du datatable en parcourant chaque ligne en mode connecté via datreader, de cette manière tu pourrais montrer l'état d'avancement...
    Pour chaque ligne parcourue avec le reader, tu recrées une ligne dans la datatable.

    P.S. : C'est aussi barbare de charger une table avec autant d'enregistrement et de la placer en visu dans un dataGridview, pauvre employé

  3. #3
    Expert éminent sénior Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 172
    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 172
    Points : 25 112
    Points
    25 112
    Par défaut
    pas d'accord avec sankasssss, je ne vois pas ce qu'il y a de barbare à utiliser un datareader, surtout que c'est ce que fait le dataadapter ...


    c'est notre cas aussi, on a certains écrans où on affiche plusieurs dizaines de milliers de lignes ; pour ca on utilise le virutalmode² du datagridview, le datareader, et un thread qui remplit un list(of object()) (list pour y et array pour x)
    c'est plus performant que de passer par un datatable
    le thread permet d'afficher les lignes dès leurs arrivées (toutes les 2k lignes lues avec le datareader, on rafraichit le dgv sur le thread principal) et de laisser la réactivité à l'interface (y compris les tris et filtres)

    ²: sur le datagridview, il y a une propriété virtualmode as boolean, si true, le datagridview lève un évènement à chaque fois qu'une cellule doit afficher sa valeur, à ce moment on va lire dans le list(of object())
    et en virtualmode il y a juste à dire le nombre de lignes pour que l'ascenseur soit ok

    biensur tout ceci n'offre pas les même avantages qu'un dataset ...
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  4. #4
    Modérateur
    Avatar de Sankasssss
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2006
    Messages
    1 842
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 842
    Points : 4 232
    Points
    4 232
    Par défaut
    Au temps pour moi,

    je pensais que c'était une méthode bourrine et je tape dans le mille
    Merci pour ces explications claires.

    Je testerai cela sur mes prochains gros traitement

  5. #5
    Futur Membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Août 2011
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2011
    Messages : 11
    Points : 7
    Points
    7
    Par défaut
    Désolé je ne pensais pas que quelqu'un y ait finalement répondu. Du coup j'ai fait comme vous aviez dit, et c'est vraiment une méthode bourrine si on effectue cela dans le thread principal, par contre comment on rafraichit le datagridview?
    Avec un Windows.Forms.Application.DoEvents() ?

    En tout cas merci pour les réponses.

  6. #6
    Modérateur
    Avatar de Sankasssss
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2006
    Messages
    1 842
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 842
    Points : 4 232
    Points
    4 232
    Par défaut
    Pourquoi ne fais-tu pas comme Pol63 te l'a conseillé avec un thread dédié, c'est bien plus professionnel qu'un doEvents...

    P.S. : Tu peux régler ton compte pour être averti par e-mail des réponses, c'est plus pratique

  7. #7
    Futur Membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Août 2011
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2011
    Messages : 11
    Points : 7
    Points
    7
    Par défaut
    Me revoilà,
    Bon entre temps j'ai progressé sous vb.net, j'ai également repris ce projet. J'ai crée un thread dédié ajoutant les données au datagridview ligne par ligne.

    Désormais, mon nouveau soucis est la lenteur, plus il y a de données, plus il faut de temps pour les ajouter.
    Par exemple, pour ajouter les 1000 premières lignes, il faut une seconde, voir moins, par contre pour ajouter les 1000 dernières il faut près d'une minute.
    Mon application utilise également +200 mo de ram à la fin.

    Mon code est de tout ce qu'il y a de plus basique :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    connection = New SqlConnection
                connection.ConnectionString = logbdd
                Dim cmd As SqlCommand = New SqlCommand("select * from T_Dcollect", connection)
                Dim _DataReader As SqlDataReader
                connection.Open()
                _DataReader = cmd.ExecuteReader
                Do While (_DataReader.Read)
                    DataGridView1.Rows.Add(_DataReader(0), _DataReader(1), _DataReader(2), _DataReader(3), _DataReader(4), _DataReader(5), _DataReader(6), _DataReader(7), _DataReader(8), _DataReader(9), _DataReader(10), _DataReader(11), _DataReader(12), _DataReader(13), _DataReader(14), _DataReader(15), _DataReader(16), _DataReader(17), _DataReader(18), _DataReader(19), _DataReader(20), _DataReader(21))
                  Loop
                msgbox("Finish")
                connection.Close()
    Si vous avez quelque piste pour m'aider, j’apprécirai.
    Ps : J'ai également testé le virtualmode, c'est plus rapide, mais j'ai toujours le même problème de lenteur au final.
    PS2 : Je peux avoir jusqu'à près d'1 million de lignes avec 22 colonnes (mais c'est rare).

    Merci d'avance.

  8. #8
    Expert éminent sénior Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 172
    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 172
    Points : 25 112
    Points
    25 112
    Par défaut
    le virtualmode ne perd pas de performances selon le nombre de lignes, donc tu as peut etre un soucis sur le stockage des données
    néanmoins, 1 millions de ligne à charger ca ne sera jamais rapide, même pour du stockage non graphique


    sinon tu dis que tu as un thread pour remplir le datagrid, normalement on ne peut pas modifier l'interface via un autre thread, tu perds peut etre du temps à ce moment là
    ajouter les lignes une par une par exemple n'est pas ce qu'il y a de mieux
    en virtualmode rows.add(2000) par exemple
    sans le virtualmode, voir s'il y a un beginedit ou beginupdate qui permet de gagner du temps sur de l'insert en bloc sans traitement de layout/Rendu


    tu peux aussi gagner un peu de performances sur le reader
    reader.Getvalues est plus rapide que de lire les items chacun leur tour via reader(0) reader(1)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    dim valtab(21) as object
    while reader.read
      reader.getvalus(valtab)
      dgv.rows.add(valtab(0), valtab(1) ...
    end while
    ca peut paraitre étrange, mais ca vient du fait que le reader fait tout un traitement sur l'accès à un item, que ne fait pas une variable tableau, et le getvalues doit tout faire une seule fois
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  9. #9
    Futur Membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Août 2011
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2011
    Messages : 11
    Points : 7
    Points
    7
    Par défaut
    Le temps n'est pas vraiment un problème, mais quand c'était juste pour savoir si on pouvait augmenter ce temps, car attendre près entre 5-10 min pour afficher en moyenne entre 50 000 et 150 000 est relativement long.

    Ensuite, j'utilise la méthode Delegate pour afficher les données dans le dgv.

    Sinon je n'ai pas vu d'améliorations avec les .getvalues.

    Autrement, je pensais à afficher seulement 2 colonnes du tableau, les 2 plus importantes, puis lorsque l'utilisateur clique sur l'une, ça charge dans un autre tableau les 19 autres colonnes, ça serait possible.
    Mais je viens de tester, et c'est à peine plus rapide...

    En tout cas merci pour votre réponse rapide.

  10. #10
    Expert éminent sénior Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 172
    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 172
    Points : 25 112
    Points
    25 112
    Par défaut
    Citation Envoyé par PurpleJesus Voir le message
    Le temps n'est pas vraiment un problème, mais quand c'était juste pour savoir si on pouvait augmenter ce temps
    ??

    Citation Envoyé par PurpleJesus Voir le message
    car attendre près entre 5-10 min pour afficher en moyenne entre 50 000 et 150 000 est relativement long.

    tu as du raté quelque chose, car moi mon datagrid rempli 200 000 lignes en 5 ou 10 secondes, et à travers le réseau
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  11. #11
    Futur Membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Août 2011
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2011
    Messages : 11
    Points : 7
    Points
    7
    Par défaut
    Citation:
    Envoyé par PurpleJesus Voir le message
    Le temps n'est pas vraiment un problème, mais quand c'était juste pour savoir si on pouvait augmenter ce temps
    ??
    Oula je suis fatigué. Ce que je voulais dire c'est que si il faut attendre, j'attendrais pour avoir les données ce n'est pas un problème. Et je cherchais à savoir pourquoi l'import était vraiment plus rapide au début qu'à la fin.

    Bref, demain je me crée un nouveau projet où je prends tout à zéro pour mettre ça au clair.

  12. #12
    Futur Membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Août 2011
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2011
    Messages : 11
    Points : 7
    Points
    7
    Par défaut
    Bon après m'être arraché les cheveux de la tête j'ai trouvé, il s'agissait de la fonction des 2 fonctions d'AutoSize du dgv, en les mettant sur None, je gagne environ 10 minutes.

    Merci à vous pour l'aide et les conseils très utiles.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Image dans Bdd (Sql Serveur ) avec model edmx
    Par GilardeauG dans le forum Linq
    Réponses: 1
    Dernier message: 26/10/2009, 16h29
  2. remplir une Bdd sql serveur a travers un formulaire Asp.net
    Par mead_Developper dans le forum ASP.NET
    Réponses: 9
    Dernier message: 28/05/2009, 11h36
  3. Remplir datagrid depuis sql server
    Par ndiayebass dans le forum C#
    Réponses: 1
    Dernier message: 30/04/2008, 09h49
  4. connexion bdd sql serveur locale
    Par eric8787 dans le forum VB.NET
    Réponses: 2
    Dernier message: 03/12/2007, 20h21

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