Russian Qt Forum
Ноябрь 27, 2024, 06:06 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: Совет по многопоточности при работе с базами..  (Прочитано 10645 раз)
kibsoft
Хакер
*****
Offline Offline

Сообщений: 625


Просмотр профиля WWW
« : Февраль 14, 2010, 12:16 »

Есть примерно 58000 записей, я их через execBatch() забиваю в базу (СУБД ORACLE), на это уходит около 4 секунд..вопрос: если например запись в базу разбить на два потока, то можно ускорить запись? Хотя бы теоретически это возможно?
Записан

http://kibsoft.ru - Download the Qt Media Encoding Library here

The apps that were written using QtMEL:
http://srecorder.com - Screen recording software
BlackTass
Гость
« Ответ #1 : Февраль 14, 2010, 16:11 »

Должно помочь по идее. Делаете два треда, в каждом создаете коннекшен и половину записей батчите в одном, половину в другом
Записан
sne
Гость
« Ответ #2 : Февраль 14, 2010, 21:53 »

а еще очень могут помочь транзакции + query::prepare(), заместо query::exec(), если конечно это все уже не используется.
Записан
BRE
Гость
« Ответ #3 : Февраль 14, 2010, 22:01 »

А мне кажется, что использование нескольких потоков ощутимого ускорения не добавит. Все равно запросы к одной таблицы на сервере будут в очередь складываться и выполняться последовательно.
Записан
BlackTass
Гость
« Ответ #4 : Февраль 14, 2010, 23:25 »

А мне кажется, что использование нескольких потоков ощутимого ускорения не добавит. Все равно запросы к одной таблицы на сервере будут в очередь складываться и выполняться последовательно.
Это уже надо тестировать. Фиг его знает что в оракле наворочено. Может там основное то время на коннект с сервером тратится.
Записан
BRE
Гость
« Ответ #5 : Февраль 14, 2010, 23:58 »

Может там основное то время на коннект с сервером тратится.
Так а что тогда ускорят несколько потоков?
Записан
break
Гипер активный житель
*****
Offline Offline

Сообщений: 846


Просмотр профиля
« Ответ #6 : Февраль 15, 2010, 01:01 »

Терзают смутные сомнения что пока реально не требуется оптимизации именно кода пишущего в БД - лучше с потоками не эксперементировать.

Возможны интересные ситуации - например если одна из записей откажется вставляться в таблицу из-за "вторичного ключа", а записи вставляемые во втором потоке зависели бы от этой невставленной записи также по вторичному ключу...

Это конечно более актуально при вставке записей в разные таблицы, но все равно возможно.
Записан
voronElf
Гость
« Ответ #7 : Февраль 15, 2010, 07:24 »

похожая ситуация была у меня, только не Oracl (к сожалению), а с sqlite я работал. Надо было больше 100 000 insert запросов сделать побыстрее, тратилось времени полчаса на это дело, разбил всю операцию на транзакции (по 500 запросов в каждой), процесс теперь успевает в 3 минуты. Я понимаю что способ очень некрасивый, но другого не нашел.
Записан
sne
Гость
« Ответ #8 : Февраль 15, 2010, 08:11 »

Я понимаю что способ очень некрасивый, но другого не нашел.
Для SQLite можно асинхронный режим "PRAGMA synchronous = ON;" работы с хранилищем попробовать включить, вероятно результаты без транзакций и с транзакциями, при этом, будут примерно равны.

ЗЫ
Описка, "PRAGMA synchronous = OFF;" конечно же Улыбающийся
« Последнее редактирование: Февраль 15, 2010, 23:22 от sne » Записан
Tonal
Гость
« Ответ #9 : Февраль 15, 2010, 08:21 »

А смотреть что именно тормозит не пробовал? Улыбающийся
Тормозить может (грубо):
1. Подготовка данных для заливки.
2. Передача данных на сервер.
3. Обработка сервером.
Разбивая заливку на 2 потока скорость какой именно части изменится?
Записан
voronElf
Гость
« Ответ #10 : Февраль 15, 2010, 09:13 »

Цитировать
Для SQLite можно асинхронный режим "PRAGMA synchronous = ON;"

Да можно, это даст тот же эффект (не будет блокировки таблицы на каждом запросе)

PS: есть у меня подозрение, что Ораклу транзакции не сильно помогут, но надо тестить
Записан
ритт
Гость
« Ответ #11 : Февраль 15, 2010, 09:43 »

http://www.linuxjournal.com/article/9602
Записан
break
Гипер активный житель
*****
Offline Offline

Сообщений: 846


Просмотр профиля
« Ответ #12 : Февраль 15, 2010, 14:01 »

Цитировать
Для SQLite можно асинхронный режим "PRAGMA synchronous = ON;"

Кстати в FB тоже такой режим есть Forced Write - при его выключении работа БД сильно ускорялась, в свое время как раз использовал для таких больших импортов...
Записан
Amigo_sa
Гость
« Ответ #13 : Февраль 15, 2010, 14:53 »

похожая ситуация была у меня, только не Oracl (к сожалению), а с sqlite я работал. Надо было больше 100 000 insert запросов сделать побыстрее, тратилось времени полчаса на это дело, разбил всю операцию на транзакции (по 500 запросов в каждой), процесс теперь успевает в 3 минуты. Я понимаю что способ очень некрасивый, но другого не нашел.
Использовать транзакции - очень даже красивое решение Улыбающийся
Разработчики сами предлагают такой путь.
Записан
break
Гипер активный житель
*****
Offline Offline

Сообщений: 846


Просмотр профиля
« Ответ #14 : Февраль 15, 2010, 15:29 »

Цитировать
Использовать транзакции - очень даже красивое решение
Это кстати позволит отменить изменения целого блока - если одна из записей не всавилась, правде в некоторых серверах для этого еще удобнее savepoints.
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.05 секунд. Запросов: 23.