Версия для печати темы
Форум на CrossPlatform.RU _ Qt Разработка баз данных _ Многопоточность при работе с БД
Автор: kibsoft 14.2.2010, 12:17
Есть примерно 58000 записей, я их через execBatch() забиваю в базу (СУБД ORACLE), на это уходит около 4 секунд..вопрос: если например запись в базу разбить на два потока, то можно ускорить запись? Хотя бы теоретически это возможно?
Автор: ViGOur 14.2.2010, 12:32
Это как я понимаю уже нужно обращаться к специфике работы самих БД.
Может не оптимальна настройка самой БД может еще чего...
Автор: Litkevich Yuriy 14.2.2010, 14:14
kibsoft, при вставке больших пачек данных, обычно блокируют (отключают) индексы, а после вставки включают вновь. Т.к. индексация осуществляется во время добавления (вставки) данных
Автор: SABROG 14.2.2010, 15:15
Можно попробовать вызывать BEGIN TRANSACTION перед вставкой, и COMMIT TRANSACTION после. И заливать данные не в таблицу, которую ты собираешься добавлять данные, а сначала во временную, а уже из неё копировать в оригинальную: INSERT INTO TABLE2 SELECT * FROM TABLE1
Автор: kibsoft 15.2.2010, 17:53
Цитата(Litkevich Yuriy @ 14.2.2010, 15:14)
kibsoft, при вставке больших пачек данных, обычно блокируют (отключают) индексы, а после вставки включают вновь. Т.к. индексация осуществляется во время добавления (вставки) данных
Отключаю, после выполнения запроса вставки включаю, но выдает ошибку:
"ORA-01502: index 'CHASTDICT.WORDIND' or partition of such index is in unusable state
Вот код:
qDebug()<<query.exec("ALTER INDEX WORDIND UNUSABLE");
query.prepare("INSERT INTO WORDS(WORD,COUNT) VALUES(?,?)");
keys=QVariant(insertBase.keys()).toList();
values=insertBase.values();
query.addBindValue(keys);
query.addBindValue(values);
qDebug()<<query.execBatch();
qDebug()<<query.lastError().databaseText();
qDebug()<<query.exec("ALTER INDEX WORDIND REBUILD");
Автор: MoPDoBoPoT 15.2.2010, 18:41
Цитата(kibsoft @ 15.2.2010, 17:53)
...
query.prepare("INSERT INTO WORDS(WORD,COUNT) VALUES(?,?)");
query.addBindValue(keys);
query.addBindValue(values);
...
Так Оракл же даржит именное связывание, а не позиционное. Попробуй так:
query.prepare("INSERT INTO WORDS(WORD, COUNT) VALUES(:word, :count)");
keys=QVariant(insertBase.keys()).toList();
values=insertBase.values();
query.bindValue(":word", keys);
query.bindValue(":count", values);
qDebug()<<query.execBatch();
Автор: kibsoft 15.2.2010, 19:17
Цитата(MoPDoBoPoT @ 15.2.2010, 19:41)
Цитата(kibsoft @ 15.2.2010, 17:53)
...
query.prepare("INSERT INTO WORDS(WORD,COUNT) VALUES(?,?)");
query.addBindValue(keys);
query.addBindValue(values);
...
Так Оракл же даржит именное связывание, а не позиционное. Попробуй так:
query.prepare("INSERT INTO WORDS(WORD, COUNT) VALUES(:word, :count)");
keys=QVariant(insertBase.keys()).toList();
values=insertBase.values();
query.bindValue(":word", keys);
query.bindValue(":count", values);
qDebug()<<query.execBatch();
Не в этом дело..без отлючения/влючения индекса и с позиционным работает...но дольше вставка идет чем без индекса, но зато обновление базы с индексом намного быстрее.. вот я и хочу на время вствки его отключать, но видимо так нельзя..
Автор: Litkevich Yuriy 15.2.2010, 19:38
kibsoft, ты транзакции используешь?
Автор: MoPDoBoPoT 15.2.2010, 20:07
Цитата(kibsoft @ 15.2.2010, 19:17)
Не в этом дело..без отлючения/влючения индекса и с позиционным работает...но дольше вставка идет чем без индекса, но зато обновление базы с индексом намного быстрее.. вот я и хочу на время вствки его отключать, но видимо так нельзя..
Я в курсе. Конечной целью у тебя является увеличить скорость записи данных в БД, потому я и сделал замечание. Собственно, подготовка запроса (prepare) служит для того, чтобы СУБД разобрало текст запроса один раз и поместила его в библиотечный кэш, а пользовалось им много раз (сам разбор запроса занимает некоторое время).
Насчет индексов - спроси про это на sql.ru, там прохаванные в этом люди.
Цитата(Litkevich Yuriy @ 15.2.2010, 19:38)
kibsoft, ты транзакции используешь?
Так он же execBatch() пользуется, там уже оптимизировано в этом плане.
Автор: Litkevich Yuriy 15.2.2010, 20:24
Цитата(MoPDoBoPoT @ 15.2.2010, 23:07)
там уже оптимизировано в этом плане.
вот не могу вспомнить/найти, где это обсуждалось. Явное использование транзакции помогало ускорить процесс.
Автор: kibsoft 15.2.2010, 20:45
Не явно их не использую..а как beginTransaction() у QSqlDriver?
просто в БД я вообще не силен, по ним ничего толком не читал..
Автор: MoPDoBoPoT 15.2.2010, 21:07
Цитата(Litkevich Yuriy @ 15.2.2010, 20:24)
вот не могу вспомнить/найти, где это обсуждалось. Явное использование транзакции помогало ускорить процесс.
Ну да, при последовательном выполнении инструкций, но здесь используется execBatch(), который поддерживается Ораклом. В этом случае данные пакуются в массивы и передаются на сервер, где уже вставляются. По-моему так
Но попробовать явно начать-закончить транзакцию все равно стоит, а то мало ли (:
Автор: Litkevich Yuriy 15.2.2010, 21:20
Цитата(MoPDoBoPoT @ 16.2.2010, 0:07)
Но попробовать явно начать-закончить транзакцию все равно стоит, а то мало ли (:
тем более, что это не сложно:
QSqlDatabase::database().transaction();
...
QSqlDatabase::database().commit();
Автор: kibsoft 15.2.2010, 21:35
Цитата(Litkevich Yuriy @ 15.2.2010, 22:20)
Цитата(MoPDoBoPoT @ 16.2.2010, 0:07)
Но попробовать явно начать-закончить транзакцию все равно стоит, а то мало ли (:
тем более, что это не сложно:
QSqlDatabase::database().transaction();
...
QSqlDatabase::database().commit();
При явном указании ничего не изменилось
На sql.ru дали вот такой запрос:
alter session set skip_unusable_indexes=true, ошибка теперь не выводится и execBatch() возвращает true, но данные в таблицу не заносятся
Автор: MoPDoBoPoT 18.2.2010, 19:02
Чем, собственно, все закончилось?
Автор: kibsoft 20.2.2010, 0:19
Цитата(MoPDoBoPoT @ 18.2.2010, 20:02)
Чем, собственно, все закончилось?
Кончилось все хорошо, с 6 секунд парсинга и записи в БД "Войны и мир" ускорил до 1,6
Автор: Litkevich Yuriy 20.2.2010, 0:58
Цитата(kibsoft @ 20.2.2010, 3:19)
Кончилось все хорошо, с 6 секунд парсинга и записи в БД "Войны и мир" ускорил до 1,6
чем ускорил?
Автор: kibsoft 20.2.2010, 12:46
Цитата(Litkevich Yuriy @ 20.2.2010, 1:58)
Цитата(kibsoft @ 20.2.2010, 3:19)
Кончилось все хорошо, с 6 секунд парсинга и записи в БД "Войны и мир" ускорил до 1,6
чем ускорил?
Все оставил прежним, но индекс сделал не уникальным(уникальность у меня проверяется в программе). Ну и убрал лишний столбец ID с автоинкрементом(незнаю зачем вообще его в данном случае делал..)
Форум Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)