2017-09-05 1 views
0

J'ai une application en C++ et je suis en utilisant le C++ Mysql Connecteur (https://dev.mysql.com/downloads/connector/cpp/)C++ Insérer dans base de données mySQL

je dois sauver quelques journaux à l'intérieur d'une table.Depending les fois où je peux avoir de grandes quantités de des données de l'ordre de milliers (par exemple, 80 000).

J'ai déjà implémenté une fonction qui réitère mes std::vector<std::string> et enregistre les std::string dans ma base de données.

Par exemple:

std::vector<std::string> lines = explode(filedata, '\n'); 
for (int i = 0; i < lines.size(); i++) 
{ 
    std::vector<std::string> elements = explode(lines[i], ';'); 
    ui64 timestamp = strtol(elements.at(0).c_str(), 0, 10); 
    std::string pointId = elements.at(6); 
    std::string pointName = elements.at(5); 
    std::string data = elements.at(3); 

    database->SetLogs(timestamp, pointId, pointName, data); 
} 

Les journaux proviennent de fichier csv, je sauverai tous les champs à mon vecteur. Après cela, je pars le vecteur (avec exploser) et obtenir seulement les champs que j'ai besoin d'enregistrer.

Mais j'ai un problème. Si j'ai par exemple 80 000, j'appelle ma fonction pour enregistrer dans la base de données 80 000. Cela fonctionne et enregistre correctement toutes les données mais cela prend beaucoup de temps.

Existe un moyen de sauvegarder toutes les données en n'appelant qu'une seule fois la fonction de sauvegarde sans appeler par exemple 80 000 et ainsi optimiser le temps?

EDIT 1

je modifier le code d'insertion à ceci:

std::string insertLog = "INSERT INTO Logs (timestamp,pointId,pointName,data) VALUES (?,?,?,?)"; 

    pstmt->setString(1, timestampString); 
    pstmt->setString(2, pointId); 
    pstmt->setString(3, pointName); 
    pstmt->setString(4, data); 
    pstmt->executeUpdate(); 
+0

Si le code que vous avez fonctionne correctement, et que vous voulez seulement améliorer les performances: [codereview.stackexchange.com] (https://codereview.stackexchange.com/) est le meilleur endroit pour poser de telles questions. –

+0

peut-être vous cherchez l'insertion builk https://dev.mysql.com/doc/refman/5.5/fr/optimizing-innodb-bulk-data-loading.html – sam

Répondre

0

Vous pouvez modifier le code pour effectuer des insertions en vrac, plutôt que d'insérer une ligne à la fois.

Je recommande de le faire en générant une instruction d'insertion sous forme de chaîne et en passant la chaîne à mysqlpp::Query. Je suppose que vous pouvez utiliser une instruction préparée pour faire des insertions en bloc d'une manière similaire.

Si vous faites une instruction d'insertion pour chaque ligne (ce que je suppose le cas ici en utilisant explode()), je pense qu'il y a beaucoup plus de trafic entre le client et le serveur, ce qui doit ralentir les choses.

EDIT

Je doute la fonction explode() pour augmenter le temps d'exécution que vous accédez au fichier deux fois lorsque vous appelez éclatez deux fois. Ce serait bien si vous pouviez produire le code pour explode().

+0

Merci pour la réponse. S'il vous plaît voir ma question initiale, j'ajoute un "Edit 1". Je pense que maintenant c'est plus rapide avec le nouveau code mais on passe 4min pour enregistrer 55748 registres en base de données ... c'est beaucoup non? – rrMM84

+0

Pouvez-vous s'il vous plaît dire la matrice précédente? Le temps requis précédemment? –

+0

4 minutes peuvent encore être optimisées si vous améliorez votre logique pour réduire le nombre d'accès aux fichiers. –