LINUX.ORG.RU

Много-много insert в SQLite в QSqlDatabase, как еще можно ускорить?

 , ,


1

4

Есть программка, которая делает сотни миллионов insert в SQLite в QSqlQuery через prepare. Transaction есть, закрываю на каждые несколько сотен тысяч вставок. Вопрос, какие варианты есть это ускорить без выключения механизмов надежности базы? Там пара не сложных таблиц, и запросы insert идут вперемешку с другими запросами. Ускорит ли если я переделаю, что insert в одну таблицу будут идти последовательно пачками, или это не играет роли? Или если переделаю на непосредственный sqlite3_exe с callback? Есть пара запросов update, ускорит ли их, если обновлять буду пачками в последовательности возрастания primary key, или не влияет?

Используются PRAGMA TEMP_STOR=MEMORY и PRAGMA JOURNAL_MODE=PERSIST.

Наблюдается неприятная штука, что вставка пока таблицы меньше 100тыс записей идет раз в двадцать быстрее чем когда они уже за пару миллионов записей. Может здесь есть какая-нибудь переиндексация?

Ответ на: комментарий от anonymous

Действительно стоит ли мучатся? Ну не для этого она предназначена.

По упоминаниям в интернете, в SQLite чуть быстрее это работает, чем в MySql. В моем случае работа с базой однопользовательская. Если есть более подходящие базы, дающие существенное прибавление, а не на 5-10%, то какие?

victor79 ()
Ответ на: комментарий от anonymous

копаешь траншею лопатой, когда нужен экскаватор?

Или канавка вместо траншеи. Чо можно такого миллионами собирать в простые таблицы, что нельзя сагрегировать по месту и скидывать только промежуточные итоги? Коллайдер гоняет пацан?

anonymous ()

Наблюдается неприятная штука, что вставка пока таблицы меньше 100тыс записей идет раз в двадцать быстрее чем когда они уже за пару миллионов записей. Может здесь есть какая-нибудь переиндексация?

Естественно, при вставке нового значения SQLite должен обновить индексы. Их размер тоже растёт с ростом базы.

anonymous ()

Как и писали выше, на вставку сильно влияют индексы. Быстрее получится, если перед вставкой убрать индесы, а после вставки их добавить. Но поскольку у тебя в момент вставки идут запросы, возможно, тебе это не подойдет.

Запросы идут по только по старым данным? Если так, то можно попробовать вставлять данные во временную базу, а потом просто поменять их местами.

У тебя написано, что таблицы простые, может быть стоит попробовать более простые key-value базы данных.

Если данные влезут в память, можно попробовать какие-нибудь in-memory БД. Типа мейлрушного тарантула или еще чего подобного. Тарантулом не пользовался, но он умеет делать свои снапшоты на диск, т.е. даже в случае падения данные не потеряются.

dr15 ()
Ответ на: комментарий от victor79

мат.статистика, сотнями миллионов и больше, пока диск не забьется.

Если сотнями миллионов, и в итоге у тебя получается база размером в несколько террабайт и тебе нужны индексы и рандомный доступ к любой записи? Если это какая-то статистика и каждая запись занимает неколько байт/килобайт и ты ими умудряешься забивать террабайты, то я сильно сомневаюсь, что sqlite это потянет. Даже если ты подтюнишь БД и она станет работать на 10% быстрее, тебе это не поможет.

Тут нужно менять саму архитектуру, выделять несколько машин, применять какое-нибудь шардирование и т.п.

dr15 ()

Посмотри :memory: еще.

Вообще, самый быстрый инсерт теоретически д.б. из файла в каком нибудь специализированном формате.

Небольшой прирост есть при вставке пачками

anonymous ()
Ответ на: комментарий от cvv

Это зависит от задачи. Может LMDB?

Нашел такой бенчмарк: https://web.archive.org/web/20140809204443/http://symas.com/mdb/microbench/ В нем, для OpenLDAP (оно же вроде LMDB?) для последовательной пакетной вставки выполняется 2.5млн записей в секунду против 100тыс для SQLite3. И чтение на порядок быстрее чем SQLite3. То что нужно. Остается вопрос насколько она замедляется с увеличением базы, о чем в тех тестах не упоминается. Пошел изучать LMDB.

victor79 ()