1. #1
    Futur Membre du Club
    Homme Profil pro
    Lycéen
    Inscrit en
    juillet 2017
    Messages
    16
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : juillet 2017
    Messages : 16
    Points : 8
    Points
    8

    Par défaut Calculs de base non optimisés (très long)

    Bonjour,
    je suis tjs dans le cadre de la conversion d'un code VBA (où je réalisais un certain nb de calculs sur des données simplement stockées dans une feuille Excel + transfert dans une matrice au lancement de l'algo) à un code VB.Net où mes données sont désormais dans une base ACCESS.

    Evidemment, étant débutant, je tâtonne pour chaque opération/chaque syntaxe et chaque opération me prend un tps ridiculement long et aboutit à un code vraiment pas optimisé (je n'utilise pas les fonctions les plus rapides mais, en essayant plusieurs, j'utilise celle qui fonctionne/ne me renvoie pas de message d'erreur).

    Exemple: à un moment je calcul qq stats de base

    Table1 contient notamment des données numériques (COL2) et des indicatrices (IND1). Colonnes que je souhaite sommer pour une valeur spécifiée du champ COL1.

    En VB je lisais simplement la colonne et en sommais les valeurs.
    En SQL je me dis qu'on peut faire bcp plus rapidement et pourtant, à force de buter sur des pb de syntaxe, j'utilise au final la solution suivante:

    Voici mon 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
     
    strConn = "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=C:\Users\b4ruk\Documents\BD1.mdb;"
    strSql = "SELECT Table1.* FROM Table1"
    ObjetConnection = New OleDbConnection()
    ObjetConnection.ConnectionString = strConn
    ObjetConnection.Open()
    ObjetCommand = New OleDbCommand(strSql)
    ObjetDataAdapter = New OleDbDataAdapter(ObjetCommand)
    ObjetCommand.Connection() = ObjetConnection
    ObjetDataAdapter.Fill(ObjetDataSet, "Table1")
    ObjetDataTable1 = ObjetDataSet.Tables("Table1")
     
    For i=1 to 1.000
    str1=BD(i).Evenement
     
    'Calcul du nb de fois où un événement se produit: en comptant le nb de fois où l'indicatrice IND1 vaut 1 (IND1=1 <=> l'événement qu'on veut suivre s'est produit)
    FoundRows = ObjetDataTable1.Select("COL1= " & str1 & " AND IND1 = 1")
    iResult1 = FoundRows.Count
     
    'Calcul de la somme d'une colonne
    strSql = "SELECT Table1.COL2 FROM Table1 WHERE Table1.COL1 = " & str1
    ObjetCommand = New OleDbCommand(strSql)
    ObjetDataAdapter = New OleDbDataAdapter(ObjetCommand)           
    ObjetCommand.Connection() = ObjetConnection
    myReader = ObjetCommand.ExecuteReader
     
    Do While myReader.Read()
         BD(i).Somme = BD(i).Somme + myReader.GetString(0)
    Loop
    myReader.Close()
     
    Next i
    J'ai écrit une 30 aine de calculs/sommation de ce genre x disons 1.000 fois (calcul pour 1.0000 valeurs de str1). Donc disons 30.000 fois des calculs comme ci-dessus, réalisés sur Table1 qui ne fait que 10.000 lignes (la table risque de grandir fortement à l'usage, raison pour laquelle j'essaie de passer de VBA à VB.Net + base ACCESS).
    Et ce calcul prend une 40aine de secondes, contre 1 ou 2 en VBA en stockant simplement les données dans une matrice.

    Mon intuition:
    -Le calcul du nb de fois où l'indicatrice IND1 vaut 1 est certainement maladroit mais je suppose qu'il n'est pas très chronophage
    -Le calcul de la somme de la colonne COL2 est probablement ce qui est le plus mal programmé. Çà doit manger énormément de tps.
    Dans un tutoriel du site j'ai vu qu'on évoquait l'utilisation d'une méthode ExecuteScalar mais je n'ai pas réussi à la faire fonctionner (oui les débuts sont vraiment très difficiles lol).
    Si ExecuteScalar est la solution , quelle en serait la syntaxe dans mon exemple, avec l'option SUM ?

    (Note: la coexistence dans mon code de la solution 'matrice' (BD(i)) et de la solution SQL/ACCESS est a priori temporaire, le temps que je bascule tout mon programme VB vers une solution ACCESS totale, enfin à espérer que j'arrive à me dépatouiller de mes soucis de conception).
    Souvenez vous de vos débuts, soyez indulgents svp

    Au plaisir de vous lire !

  2. #2
    Expert confirmé
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    février 2010
    Messages
    2 991
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : février 2010
    Messages : 2 991
    Points : 4 926
    Points
    4 926
    Billets dans le blog
    1

    Par défaut

    Bonjour,

    Pour faire simple, la différence entre ton ancien code et ton nouveau, c'est que le nouveau exécute 1000 (ou 30000 j'ai pas bien compris) requêtes dans la base de données.
    Ce qui est une hérésie : si t'as une boucle qui effectue une requête à chaque itération, c'est que ta requête est mal écrite. Le SQL est un langage ensembliste, et est donc fait pour traiter en masse des données, pas faire du ligne à ligne.

    Vous pouvez simplement changer votre requête en :
    Code sqm : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT Table1.COL1, sum(Table1.COL2) FROM Table1 GROUP BY Table1.COL1

    Ainsi, vous n'avez plus besoin de boucler, et vous aurez l'ensemble des sommes de COL2 par valeur distincte de COL1 en moins d'une seconde.

    Dernier point : ACCESS est tout sauf un bon SGBDR (c'est pas le pire non plus, mais il n'en est pas loin).
    Le principal avantage d'Access, c'est de proposer une GUI permettant d'écrire facilement des programmes gérant des données en VBA, chose que vous ne souhaitez plus faire.

    Orientez-vous donc plutôt vers SQL Server Express ou SQL Server LocalDB qui sont des éditions gratuites de Microsoft SQL Server qui est le meilleur SGBDR du marché (en gros vous passez de la Ford T au TGV).
    On ne jouit bien que de ce qu’on partage.

  3. #3
    Futur Membre du Club
    Homme Profil pro
    Lycéen
    Inscrit en
    juillet 2017
    Messages
    16
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : juillet 2017
    Messages : 16
    Points : 8
    Points
    8

    Par défaut

    Citation Envoyé par StringBuilder Voir le message
    Bonjour,

    Pour faire simple, la différence entre ton ancien code et ton nouveau, c'est que le nouveau exécute 1000 (ou 30000 j'ai pas bien compris) requêtes dans la base de données.
    Ce qui est une hérésie : si t'as une boucle qui effectue une requête à chaque itération, c'est que ta requête est mal écrite. Le SQL est un langage ensembliste, et est donc fait pour traiter en masse des données, pas faire du ligne à ligne.

    Vous pouvez simplement changer votre requête en :
    Bonjour,
    merci pour ta réponse.
    Le nouveau code fait bien 30.000 requêtes.
    Table1 est ma base de données de base.
    La Matrice BD(1 To 30 , 1 To 1.000) qui fait 1.000 lignes, est remplie est effectuant 30 requêtes pour remplir chacune des 1.000 lignes de BD(i)
    Donc en gros, 1 requête effectuée sur Table sert à remplir BDE(i,j), soit 1.000 x 30 = 30.000 données à calculer.

    Je regarde la suite de ta réponse.

  4. #4
    Futur Membre du Club
    Homme Profil pro
    Lycéen
    Inscrit en
    juillet 2017
    Messages
    16
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : juillet 2017
    Messages : 16
    Points : 8
    Points
    8

    Par défaut

    Citation Envoyé par StringBuilder Voir le message
    Bonjour,


    Vous pouvez simplement changer votre requête en :
    Code sqm : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT Table1.COL1, sum(Table1.COL2) FROM Table1 GROUP BY Table1.COL1
    Sur tes conseils, j'ai donc :
    1. Créé une table avec le SELECT que tu proposes, sur mes 30 colonnes à sommer
    2. Lu ces données avec un OleDBDataReader (solution a priori temporaire)
    Le calcul des 30.000 stats est donc fait en une fois, par contre je parcours ligne à ligne chacune des 1.000 lignes du reader pour lire les stats calculées et les mettre dans une matrice VBA.
    Le temps de calcul repasse ainsi sous les 2 secondes.

    Remarque: lorsque le programme sera fonctionnel, je vais voir pour me débarrasser de cette matrice VB (nommée "BD(i)" dans mon prog) de stats (1.0000 lignes et 30 colonnes) afin de tout gérer avec ACCESS et SQL.

    Une fois ceci fait , je vais laisser la base de données grandir un peu et essayer de passer vers un SGBDR plus rapide sur tes conseils.
    Je constate en effet pour le moment que l'enregistrement de nouvelles données ("lignes") est vraiment très long mais peut être (probablement) est -ce mon code qui est mal pensé.


    En te remerciant vivement, je vais clore le sujet... pour surement en ouvrir un nouveau dans qq jours

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

Discussions similaires

  1. [10gR2] Calcul de statistiques et temps de sauvegarde très longs
    Par korian dans le forum Administration
    Réponses: 0
    Dernier message: 04/08/2015, 15h50
  2. Très long texte dans Quick Report - Comment faire ?
    Par delphi+ dans le forum Composants VCL
    Réponses: 2
    Dernier message: 21/08/2005, 22h18
  3. [Debutant]calcul de valeurs propres, givens-householder
    Par malbarre dans le forum Général Algorithmique
    Réponses: 12
    Dernier message: 18/08/2005, 16h40
  4. Réponses: 15
    Dernier message: 08/08/2005, 18h30
  5. [debutant][Classpath][Linux] Classe non trouvée
    Par oghma777 dans le forum Général Java
    Réponses: 5
    Dernier message: 15/10/2004, 21h26

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