[gelöst] QT und MYSQL lokal = schnell, remote = langsam

Verschiedenes zu Qt
Antworten
linny
Beiträge: 5
Registriert: 20. August 2009 02:19

[gelöst] QT und MYSQL lokal = schnell, remote = langsam

Beitrag von linny »

Hallo zusammen,
ich arbeite erst seit ein paar Wochen mit Qt.
Ich hab mich auch recht schnell zurechtgefunden, aber jetzt bin ich an einem Punkt an dem ich nicht weiterkomme.

Ich hab eine Anwendung geschrieben, die auf eine MySql Datenbank zugreift. Dabei arbeitet die Anwendung mit relativ vielen Datensätzen, bis zu 150.000 auf einmal.

Mein Problem ist jetzt, wenn ich die Anwendung mit einem lokalen MySql Server teste, läuft alles normal schnell (ca. 6 Sekunden). Wenn ich jedoch die Datensätze (in diesem Fall 76.000) auf einen entfernten MySql Server übertragen will, braucht er extremst lange (> 3 Stunden).
An der Internetverbindung kann es nicht liegen, die wird nicht mal zu 10% ausgelastet.
Die Namensauflösung kann es eigentlich auch nicht sein. Der MySql Server hat die option skip-name-resolv und eine Verbindung über die Konsole zu dem Server ist auch recht flott.

Ich komm einfach nicht weiter. Hat jemand eine Idee was es sein könnte?


Ps.: Noch als Randinformation. Die Datensätze werden aus einer Textdatei in ein TableWidget zur Bearbeitung gelesen und von dort dann zeilenweile per While-Schleife in ein QSqlQuery geschrieben und auf den Server übertragen.
Gruß
Linny
Zuletzt geändert von linny am 21. August 2009 12:13, insgesamt 1-mal geändert.
CaptnChaos
Beiträge: 605
Registriert: 28. Juni 2007 15:01
Kontaktdaten:

Beitrag von CaptnChaos »

Netzwerkprobleme. Was hast du für einen Upstream?
linny
Beiträge: 5
Registriert: 20. August 2009 02:19

Beitrag von linny »

upstream von 1024, aber wie gesagt, die werden nicht mal zu 10 prozent genutzt. der überträgt gerade mal mit 3-4 Kb/s. wenn ich über mytop schaue, kommen da gerade mal 3 query/sec an. lokal sind es über 4000 query/sec. und die einzelnen datensätze sind auch nicht groß. sind simple adressen, mit 8 feldern.
und wie gesagt, wenn ich per mysql -u -p auf den server connecte geht es ja auch wesentlich schneller.
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

Dann hilfts nix, wir brauchen Code. Sonst bleibt es nur Gerate ;)
Also, wie du connectest, wie die Datensätze übertragen werden, usw.
linny
Beiträge: 5
Registriert: 20. August 2009 02:19

Beitrag von linny »

Ok. hier mal etwas code :)

Qt Version ist 4.5.2
geschrieben mit QtCreator 1.2.1
OS: openSUSE Linux 11.1

Connect zur Datenbank:

Code: Alles auswählen

bool connectdb()
{
    QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
    db.setHostName(QString(DB_Hostname));
    db.setDatabaseName(QString(DB_DbName));
    db.setUserName(QString(DB_UserName));
    db.setPassword(QString(DB_Password));
    db.setConnectOptions("CLIENT_COMPRESS=1;CLIENT_INTERACTIVE=1");

    if(!db.open())
    {
        QMessageBox::critical(0,"Fehler:","Keine Verbindung zur Datenbankc: " + db.lastError().text());
        return false;
    }
    else
        return true;
}
Übertragung der Daten in die Datenbank:

Code: Alles auswählen

    QSqlQuery query;
    QString sql = "SELECT kampagne_id FROM kampagne WHERE aktiv='1' and name = '"+ui->comboBox->currentText()+"';";
    query.exec(sql);
    query.next();
    QString kamp = query.value(0).toString();
    query.clear();


        int i = 0;
        int proco = 0;
        ui->progressBar->setVisible(true);
        ui->progressBar->setMaximum(ui->tableWidget->rowCount());
        ui->progressBar->setValue(0);

        while(i < ui->tableWidget->rowCount())
        {
            sql="INSERT INTO adressen (vorname, name, strasse,hausnummer, plz, ort, vorwahl, telefon,status,kampagne) values ('"+ui->tableWidget->item(i,0)->text()+"','"+ui->tableWidget->item(i,1)->text()+"','"+ui->tableWidget->item(i,2)->text()+"','"+ui->tableWidget->item(i,3)->text()+"','"+
ui->tableWidget->item(i,4)->text()+"','"+ui->tableWidget->item(i,5)->text()+"','"+ui->tableWidget->item(i,6)->text()+"','"+
ui->tableWidget->item(i,7)->text()+"','0','"+kamp+"');";
            if(!query.exec(sql))
            {
                QMessageBox::critical(0,"Fehler","Fehler bei der Abfrage: " + query.lastError().text());
            }
            else
            {
                //Nur jeden 10. Schritt in der Progressbar anzeigen.
                proco++;
                if(proco ==10)
                {
                    ui->progressBar->setValue(i);
                    proco =0;
                }
            }
            i++;
        }

        ui->progressBar->setVisible(false);
gruß
linny
solarix
Beiträge: 1133
Registriert: 7. Juni 2007 19:25

Beitrag von solarix »

Kennst du den Server? Ich meine: bis du Admin des Servers? Falls nicht (falls du z.B. den MySQL-Dienst eines Webhosters beanspruchst): WebDatenbanken sind haeufig auf Lesen optimiert (mittels RAID), nicht auf Schreiben (eine Webseite liest mehr als dass sie schreibt).

Auf jeden Fall versuchen wuerde ich folgendes:

- Weniger INSERTs, dafuer mit mehreren VALUES-Bloecken. Haenge einfach mehrere VALUES-Bloecke zusammen und fuehre den INSERT z.B. mal mit 10 oder mit 20 Datensaetzen aus.
- INSERT DELAYD (beim Import bist du ja nicht darauf angewiesen, dass die eingefuegten Daten sofort verfuegbar sind). Siehe http://dev.mysql.com/doc/refman//5.1/de ... layed.html

hth...
Zuletzt geändert von solarix am 20. August 2009 18:16, insgesamt 1-mal geändert.
linny
Beiträge: 5
Registriert: 20. August 2009 02:19

Beitrag von linny »

ok. danke. das werd ich mal probieren. bin zwar gerade nicht an meinem rechner im büro, aber wenn ich nachher zurück bin versuch ich das mal.
auf jeden fall schon mal vielen dank für den tip.
thereapman
Beiträge: 36
Registriert: 6. Juni 2007 15:39

Beitrag von thereapman »

Ich denke das problem ist die verbindung. dazu muss man verstehn wie die kommunikation mit so ner DB läuft.

Um es kurz zu fassen: ich würde auf die Latenz (Ping) tippen.
Lokal ist die Latenz zum MySQL Server fast gleich null (bissl was geht durch den Kernel drauf aber das ist eigentlich nicht messbar). Remote hast du (ich nehme jetz mal DSL an) so um die 30-40ms Latenz.

Wenn du nun jedes Insert einzeln abfeuerst. Wartet deine anwendung immer auf die nachricht der Datenbank ob alles fein säuberlich commited ist. und das denk ich ist der Punkt der so lange dauert.

Ne direkte Lösung hab ich jetzt zwar nich parrat aber denk mal in die richtung mehrere Datensätze in einem Insert zu verarbeiten.
linny
Beiträge: 5
Registriert: 20. August 2009 02:19

Beitrag von linny »

ich danke euch erstmal recht herzlich.
eure vermutungen waren goldrichtig.
es sind tatsächlich die latenzen wie thereapman vermutet hat.
ich hab zwar einige erfahrung mit mysql datenbanken, aber bisher halt fast immer lokal (sprich webanwendungen), daher hatte ich das problem noch nie.

ich hab das jetzt so gemacht wie von solarix vorgeschlagen.
ich sende immer ca. 500 datensätze mit einem insert und siehe da, die 70.000 datensätze sind innerhalb von ein paar sekunden auf dem remote-host.

Vielen Dank nochmal

Gruß
Linny
Antworten