[gelöst] QT und MYSQL lokal = schnell, remote = langsam
[gelöst] QT und MYSQL lokal = schnell, remote = langsam
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
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.
-
- Beiträge: 605
- Registriert: 28. Juni 2007 15:01
- Kontaktdaten:
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.
und wie gesagt, wenn ich per mysql -u -p auf den server connecte geht es ja auch wesentlich schneller.
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:
Übertragung der Daten in die Datenbank:
gruß
linny
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;
}
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);
linny
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...
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.
-
- Beiträge: 36
- Registriert: 6. Juni 2007 15:39
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.
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.
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
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