Версия для печати темы
Форум на CrossPlatform.RU _ Qt Разработка баз данных _ Быстрая вставка строк в базу данных mysql
Автор: evgen55 24.7.2017, 14:25
Есть база данных mysql на удаленном сервере. При обращении к таблице каждый запрос выполняется около 40 мс. Возможно ли както повысить скорость. Пробовал все это оборачивать в одну транзакцию но скорость от этого только уменьшилась
QSqlQuery query;
query.prepare("SELECT id FROM objects WHERE subject_id=:subject_id");
потом в цикле подставляю параметры
query.bindValue(":subject_id",sid);
И потом делаю
query.exec()
Цитата(evgen55 @ 24.7.2017, 14:21)
Есть база данных mysql на удаленном сервере. При обращении к таблице каждый запрос выполняется около 40 мс. Возможно ли както повысить скорость. Пробовал все это оборачивать в одну транзакцию но скорость от этого только уменьшилась
QSqlQuery query;
query.prepare("SELECT id FROM objects WHERE subject_id=:subject_id");
потом в цикле подставляю параметры
query.bindValue(":subject_id",sid);
И потом делаю
query.exec()
P.S. ОС Windows
Автор: lanz 24.7.2017, 20:35
А где собственно вставка?
Попробуйте забиндить сразу все subject_id,
SELECT id FROM objects WHERE subject_id IN :subject_id
Автор: evgen55 25.7.2017, 8:11
Запрос вставки содержит много полей поэтому не хотелось его здесь указывать
Автор: lanz 25.7.2017, 9:04
Еще так можно попробовать.
http://doc.qt.io/qt-5/qsqlquery.html#execBatch
Автор: lanz 25.7.2017, 10:09
Ну и вообще
https://dev.mysql.com/doc/refman/5.6/en/insert-optimization.html
Автор: Iron Bug 25.7.2017, 21:47
Цитата(evgen55 @ 24.7.2017, 16:25)
Возможно ли както повысить скорость.
проверь, что твоя таблица индексирована по полям, по которым происходит выборка. можно также поиграться с настройками сервера.
Автор: evgen55 27.7.2017, 16:29
Цитата(lanz @ 25.7.2017, 10:09)
Ну и вообще
https://dev.mysql.com/doc/refman/5.6/en/insert-optimization.html
qDebug() << DB.driver()->hasFeature(QSqlDriver::PreparedQueries);
qDebug() << DB.driver()->hasFeature(QSqlDriver::BatchOperations);
qDebug() << DB.driver()->hasFeature(QSqlDriver::Transactions);
Все возвращает false. Я правильно понимаю что ни пакетная вставка ни транзакции не поддерживаются? Что можно сделать?
Автор: lanz 27.7.2017, 19:09
Что тотут не так, транзакции не поддерживаются - это очень странно.
Цитата
Note that some databases need to be open() before this can be determined.
Автор: evgen55 27.7.2017, 20:40
Цитата(lanz @ 27.7.2017, 19:09)
Что тотут не так, транзакции не поддерживаются - это очень странно.
Цитата
Note that some databases need to be open() before this can be determined.
Спасибо, теперь только DB.driver()->hasFeature(QSqlDriver::BatchOperations); false Можно ли это както исправить?
Автор: lanz 28.7.2017, 16:13
Прежде всего посмотрите, где у вас задержка, в Qt? При соединении с сервером? На сервере? В зависимости от этого нужно смотреть что конкретно оптимизировать.
Автор: evgen55 31.7.2017, 8:56
Цитата(lanz @ 28.7.2017, 16:13)
Прежде всего посмотрите, где у вас задержка, в Qt? При соединении с сервером? На сервере? В зависимости от этого нужно смотреть что конкретно оптимизировать.
Любой запрос (сама функция exec) выполняется 40 милисекунд, а в phpmyadmin выполняется мгновенно
Автор: lanz 31.7.2017, 9:06
Мнгновенно это сколько в миллисекундах?
Автор: evgen55 1.8.2017, 8:16
Цитата(evgen55 @ 31.7.2017, 8:56)
Цитата(lanz @ 28.7.2017, 16:13)
Прежде всего посмотрите, где у вас задержка, в Qt? При соединении с сервером? На сервере? В зависимости от этого нужно смотреть что конкретно оптимизировать.
Любой запрос (сама функция exec) выполняется 40 милисекунд, а в phpmyadmin выполняется мгновенно
Отображение строк 0 - 24 (4274 всего, Запрос занял 0.0018 сек.)
Автор: lanz 1.8.2017, 9:13
Цитата
Отображение строк 0 - 24 (4274 всего, Запрос занял 0.0018 сек.)
Это возможно сравнение яблок с апельсинами. 0.0018 это то что показывает phpmyadmin, я если честно не знаю, как он меряет, что он включает в это время и как вы меряли 40 мс.
Приложите пожалуйста минимальный проект с бенчмарком чтобы можно было конкретно уже смотреть.
Кроме того - существует ли проблема вообще? Т.е. вы наблюдаете тормоза при вставке или вам просто не нравится число 40?
Попробуйте вставить много строк, увеличивается ли время пропорционально? Как вы меряли время?
Согласитесь, что несколько странно видеть сишный код в 20 раз медленнее php, не верю
Автор: evgen55 1.8.2017, 10:41
Цитата(lanz @ 1.8.2017, 9:13)
Цитата
Отображение строк 0 - 24 (4274 всего, Запрос занял 0.0018 сек.)
Это возможно сравнение яблок с апельсинами. 0.0018 это то что показывает phpmyadmin, я если честно не знаю, как он меряет, что он включает в это время и как вы меряли 40 мс.
Приложите пожалуйста минимальный проект с бенчмарком чтобы можно было конкретно уже смотреть.
Кроме того - существует ли проблема вообще? Т.е. вы наблюдаете тормоза при вставке или вам просто не нравится число 40?
Попробуйте вставить много строк, увеличивается ли время пропорционально? Как вы меряли время?
Согласитесь, что несколько странно видеть сишный код в 20 раз медленнее php, не верю
int id;
DB = QSqlDatabase::addDatabase("QMYSQL");
DB.setHostName("xxx.xxx.xxx.xxx");
DB.setDatabaseName("xxxxxxxx");
DB.setUserName("xxxxxxx");
DB.setPassword("xxxxxxxxxxx");
QSqlQuery* queryI;
QTime time;
queryI=new QSqlQuery(DB);
queryI->setForwardOnly(true);
queryI->prepare("INSERT INTO subtags(p_id,p_tag,item) VALUES(:p_id,:p_tag,:item)");
QSqlQuery query;
query.setForwardOnly(true);
query.prepare("SELECT id,subject_id,FROM objects");
while (query.next()) {
id=query.value(0).toString();
...
// цикл вставки где меняется p_tag и item
queryI->bindValue(":p_id",id);
queryI->bindValue(":p_tag","walling_type");
queryI->bindValue(":item",AllObject[ind].WALLING_TYPE);
time.start();
if (!queryI->exec())
qDebug()<<"error update insert WALLING_TYPE"<<id;
else qDebug()<<time.elapsed(); // здесь каждый запрос 40 мс
...
}
Соответственно когда селект возвращает примерно 4000 объектов и внутренний цикл содержит примерно 10-20 item получается слишком долго
Автор: lanz 1.8.2017, 11:21
Во первых QTime на Windows возвращает с точностью кратной то ли 15, то ли 20 мс, в любом случае, это слишком плохо.
Попробуйте QElapsedTimer, интерфейс тот же, а точность обычно лучше.
http://doc.qt.io/qt-4.8/qelapsedtimer.html
Если все равно 40 мс будет получаться, замерьте время всего цикла(с 40000-80000 вставок) и разделите, тогда получите точное время.
40000-80000 вставок это довольно много, попробуйте все таки execBatch и если не поможет, то попробуйте просто слепить в строке нужный запрос на вставку всех строк за раз и его выполнить - получите скорость вставки напрямую.
Автор: evgen55 2.8.2017, 14:23
Цитата(lanz @ 1.8.2017, 11:21)
Во первых QTime на Windows возвращает с точностью кратной то ли 15, то ли 20 мс, в любом случае, это слишком плохо.
Попробуйте QElapsedTimer, интерфейс тот же, а точность обычно лучше.
http://doc.qt.io/qt-4.8/qelapsedtimer.html
Если все равно 40 мс будет получаться, замерьте время всего цикла(с 40000-80000 вставок) и разделите, тогда получите точное время.
40000-80000 вставок это довольно много, попробуйте все таки execBatch и если не поможет, то попробуйте просто слепить в строке нужный запрос на вставку всех строк за раз и его выполнить - получите скорость вставки напрямую.
Спасибо большое, слепить запрос в одну строку помогло. execBatch пробовал он не поддерживается
Форум Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)