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

Bases de données Discussion :

Optimisation de l'accès aux bases


Sujet :

Bases de données

  1. #1
    Invité
    Invité(e)
    Par défaut Optimisation de l'accès aux bases
    Bonjour,

    je découvre Qt depuis quelques mois. Après la découverte, j'en suis au stade de l'optimisation des codes et à la comparaison avec mon point de départ, Lazarus.

    Mon premier problème "sensible" est l'insertion dans les BDD que je trouve lente aussi bien dans les tables MySQL myISAM -donc sans transaction- que dans les tables MySQL innoDB, et de manière moins sensible (en valeur absolue) dans les tables PostgreSQL. Mes bases sont hébergées sur un serveur dédié hébergé Linux 64 bits : MySQL 5.5 et pgSQL 9.1

    En MySQL, c'est une véritable catastrophe. La latence est très importante. En pgSQL c'est nettement moins bien qu'en Lazarus... C'est plus rapide qu'en MySQL mais comme avec ce dernier, le temps d'insertion est toujours quasiment le double.

    Les tables de test contiennent 2 varchar(20). La première est la clé primaire, la seconde est une clé unique.
    Voici mes codes de tests actuels en PostgreSQL.
    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
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    ##include "mainwindow.h"
    #include <QApplication>
    #include <QDebug>
     
    #include <QSqlDatabase>
    #include <QSqlError>
    #include <QSqlQuery>
    #include <QSqlTableModel>
    #include <QSqlRecord>
     
    #include <QDateTime>
    #include <QString>
    #include <QTime>
     
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        MainWindow w;
        w.show();
        QSqlDatabase db = QSqlDatabase::addDatabase("QPSQL");
        db.setHostName("xxx.xxx.xxx.xxx");
        db.setUserName("xxxxxxxxxxr");
        db.setPassword("xxxxxxxxxx");
        db.setDatabaseName("xxxxxxxxxx");
        qDebug() << db.isValid();
     
        if (!db.open()) {
             qDebug() << db.lastError();
             qDebug() << "Connexion FAILED.";
             qDebug() << "Driver disponible: " << db.drivers();
             qDebug() << "Driver fonctionnel(QPSQL): " << db.isDriverAvailable("QPSQL");
             qDebug() << "numero de l'erreur: " << db.lastError().number();
             qDebug() << "database erreur: " << db.lastError().databaseText();
             qDebug() << "driver erreur: " << db.lastError().driverText();
             qDebug() << "type erreur: " << db.lastError().type();
             qFatal("Impossible de se connecter à la base.");
        }
     
        qDebug() << "Vous êtes connecté à " << db.hostName();
        int dbcount;
        QSqlQuery query(db);
        query.exec("SELECT COUNT(*) FROM test2012");
        while (query.next()) {
          dbcount = query.value(0).toInt();
          qDebug() << dbcount;
        }
     
        bool bOK;
        int rowsToAdd = 100;  //Insertion de 100 lignes
        QString str;
        QDateTime dtnow;
        QTime time;
     
        bOK = true;
        if (db.transaction()) {
           time.start();
          query.prepare("INSERT INTO test2012 (teid, tenom) VALUES (:teid, :tenom)");
          for (int i = 0 ; i < rowsToAdd ; i++) {
            dtnow = QDateTime::currentDateTime();
            str = dtnow.toString("yyyyMMddHHmmsszzz")+ QString::number(i);
            query.bindValue(":teid", str);
            query.bindValue(":tenom", str);
            if (!query.exec()) {
               bOK = false;
               break;
            }
          }
     
          if (bOK == true) {
            db.commit();
            qDebug() << "Succès Insertion 100 - " << time.elapsed() << "millisecondes";
          } else {
            db.rollback();
            qDebug() << "Echec Insertion 100 - " << time.elapsed() << "millisecondes";
          }
        }
     
        query.exec("SELECT COUNT(*) FROM test2012");
        while (query.next()) {
          dbcount = query.value(0).toInt();
          qDebug() << dbcount;
        }
     
       time.start();
     
       QSqlTableModel model(0, db);
       model.setEditStrategy(QSqlTableModel::OnManualSubmit);
       model.setTable("test2012");
       model.select();
       int rowCount = model.rowCount();
       qDebug() << rowCount;
     
       model.database().transaction();
       if(!model.insertRows(rowCount, rowsToAdd)) {
         qDebug() << "insertRows" << model.lastError().text();
         return 0;
       }
     
       int idIndex = model.record().indexOf("teid");
       int nomIndex = model.record().indexOf("tenom");
     
       for (int i = 0 ; i < rowsToAdd ; i++) {
         dtnow = QDateTime::currentDateTime();
         str = dtnow.toString("yyyyMMddHHmmsszzz")+ QString::number(i);
         model.setData(model.index(rowCount +i, idIndex),str);
         model.setData(model.index(rowCount +i, nomIndex),str);
        }
     
        if(model.submitAll()) {
            model.database().commit();
            qDebug() << "Ecriture 100 - " << time.elapsed() << "millisecondes";
         } else {
           model.database().rollback();
           qDebug() << "Database Write Error" <<
                       "The database reported an error: " <<
                      model.lastError().text();
        }
     
       query.exec("SELECT COUNT(*) FROM test2012");
       while (query.next()) {
         dbcount = query.value(0).toInt();
         qDebug() << dbcount;
       }
     
        qDebug() << "Fermeture de la base.";
        if (db.isOpen()) {
            db.close();
        }
     
        return a.exec();
    }
    La réponse est
    true
    Vous êtes connecté à "xxx.xxx.xxx.xxx"
    7626
    Succès Insertion 100 - 4889 millisecondes
    7726
    7726
    Ecriture 100 - 6292 millisecondes
    7826
    Fermeture de la base.
    5 secondes, c'est beaucoup comparé à Lazarus qui sur la même base et sur le même appareil client (Win7-32 bits) met environ 2 secondes pour faire le même travail. Evidemment avec cette première méthode d'insertion, je pourrais certainement utiliser les tuples mais alors je ne sais pas comment utiliser une barre de progression dans cette configuration. Et puis à priori les tuples cela ne fonctionne pas avec la 2ème méthode, les TableSQLmodel.

    Et avec TableSQLmodel, 6 secondes, c'est encore plus long même si j'ai bien compris que TableSQLmodel n'est pas à privilégier pour ce type d'insertion.

    En ce qui concerne MySQL, c'est franchement mauvais ! En innoDB (avec AutoCommit = 0) l'ajout de 100 enregistrements requiert environ 9 s (8896ms). Sur une table identique en myISAM, guère mieux (8844 ms) ... Avec Lazarus, moins de 5 secondes quelque soit la table (innoDB ou myISAM). Ce que je trouve étonnant, c'est que quelque soit la méthode utilisée, il est impossible de s'approcher de Lazarus dès qu'on utilise Qt alors qu'en C++ sans Qt (#include <winsock.h> #include <MYSQL/mysql.h>), je n'ai pas noté de différence significative avec Lazarus.

    Bref, j'essaye de savoir si les codes sont adaptés, s'il y a moyen de les améliorer ou s'il existe une méthode plus pertinente (à partir de Qt)...

    Mon deuxième sujet, en cours de test, est la lecture des tables et plus précisément l'utilisation de Fetchrow et des threads... Et je dois reconnaître que je patauge au niveau de la documentation. Il y en a un peu mais je ne trouve rien vraiment d'exploitable... Si quelqu'un(e) a une bonne adresse, je suis preneur.

    Merci. Cordialement. Gilles
    Dernière modification par Invité ; 16/01/2014 à 20h24.

Discussions similaires

  1. [MySQL] Optimisation d'un accès aux bases
    Par griese dans le forum PHP & Base de données
    Réponses: 3
    Dernier message: 04/12/2006, 13h39
  2. Pilote d'accés aux bases de données
    Par aragom dans le forum Bases de données
    Réponses: 3
    Dernier message: 10/05/2005, 11h06
  3. Accès aux base de données sous Delphi 7 Edition Studio Perso
    Par renorx dans le forum Bases de données
    Réponses: 4
    Dernier message: 16/02/2005, 15h24
  4. Accès aux bases de données Access
    Par xela dans le forum C++Builder
    Réponses: 3
    Dernier message: 15/12/2004, 10h07
  5. [VB6] [BDD] Optimisation de l'accès aux données
    Par LadyArwen dans le forum VB 6 et antérieur
    Réponses: 8
    Dernier message: 30/01/2003, 14h27

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