Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум на 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)