|
Удаление данных в большой таблице
|
|||
---|---|---|---|
#18+
Здравствуйте! Использую Sqlite (версия 3.8.10.2) в составе Qt 5.6. Есть большая база с парой таблиц на ~250 000 000 записей (размер файла ~ 5Гб). Проблема - долгое выполнение запроса на удаление записей (~ 5 000 записей). Вот код запроса создания таблиц: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14.
Одному SERIE_ID соответствуют 5000 записей в таблице IMAGE со ссылкой на этот ID (который указан в качестве FOREIGN KEY). Количество записей в таблице SERIE ~ 50 000, IMAGE ~ 250 000 000. Вот такой запрос выполняется мгновенно: Код: sql 1. 2. 3.
А собственно удаление занимает на SSD 2 секунды, на обычном HDD - около минуты. Код: sql 1. 2. 3.
Тестировал эти запросы в своем приложении, и в паре сторонних утилит (SQlite Expert, DB Browser for QSlite), времена везде примерно одинаковы. Настройки базы и соединения: Код: sql 1. 2. 3. 4. 5. 6.
Собственно, вопрос: можно ли существенно улучшить время удаления, или это тупик для qslite? Как еще можно организовать логику, когда удаление большой пачки снимков периодически требуется, но минута - это недопустимо много? Спасибо. ... |
|||
:
Нравится:
Не нравится:
|
|||
30.05.2017, 17:18 |
|
Удаление данных в большой таблице
|
|||
---|---|---|---|
#18+
http://sqlite.org/wal.html Обрати внимание на девятый пункт "против". LexerysКак еще можно организовать логику, когда удаление большой пачки снимков периодически требуется, но минута - это недопустимо много?Вместо удаления, можно просто помечать запись как "больше не играть". Просто добавь в таблицу поле "Expiration_Date null" и если оно пусто - запись рабочая, если не пустая, то считать ее удаленной. Это заодно позволит смотреть историю, типа вчера были такие записи, а сегодня сякие. ... |
|||
:
Нравится:
Не нравится:
|
|||
30.05.2017, 18:16 |
|
Удаление данных в большой таблице
|
|||
---|---|---|---|
#18+
White Owl http://sqlite.org/wal.html Обрати внимание на девятый пункт "против". Размер транзакции не слишком велик. Впрочем, я попробовал разные режимы журнала - никакой разницы в скорости. White OwlВместо удаления, можно просто помечать запись как "больше не играть". Просто добавь в таблицу поле "Expiration_Date null" и если оно пусто - запись рабочая, если не пустая, то считать ее удаленной. Это заодно позволит смотреть историю, типа вчера были такие записи, а сегодня сякие. Над этим вариантом тоже думал. Но тут либо размер файла базы будет постепенно расти, либо нужно предусматривать периодически запускаемую процедуру удаления помеченных записей, и оба варианта не очень нравятся. Хотя предполагаю, что придется остановиться на первом. Попробовал подобный запрос с удалением такого же числа записей в firebird, с подобной таблицей, там все удалилось за 200ms (вместо 1000ms sqlite). ... |
|||
:
Нравится:
Не нравится:
|
|||
30.05.2017, 18:31 |
|
Удаление данных в большой таблице
|
|||
---|---|---|---|
#18+
Ну вообще-то, та версия что с Qt идет уже оооооочень старая. 3.8.6 против сегодняшней 3.19.2. Скачай амальгаму свежей версии, замени файлы в %Qt%\Src\qtbase\src\3rdparty\sqlite\ на свежие, и пересобери qsqlite плагин в %Qt%\Src\qtbase\src\plugins\sqldrivers\sqlite\ Точно избавишься от много-летних багов. ... |
|||
:
Нравится:
Не нравится:
|
|||
30.05.2017, 18:48 |
|
Удаление данных в большой таблице
|
|||
---|---|---|---|
#18+
White OwlНу вообще-то, та версия что с Qt идет уже оооооочень старая Спасибо за замечание, обновил, на скорость удаления это не повлияло. Но все равно полезно =) ... |
|||
:
Нравится:
Не нравится:
|
|||
30.05.2017, 19:28 |
|
Удаление данных в большой таблице
|
|||
---|---|---|---|
#18+
Lexerys, Попробуй: 1. Использовать транзакции. (значительно уменьшает время) 2. Сделать бэкап базы, разверни бэкап в in_memory, там удали и скинь назад. ... |
|||
:
Нравится:
Не нравится:
|
|||
01.06.2017, 17:00 |
|
Удаление данных в большой таблице
|
|||
---|---|---|---|
#18+
Уважаемый автор, Lexerys(размер файла ~ 5Гб). Уважаемый авторразверни бэкап в in_memory, там удали и скинь назад Что-то не верится в увеличении производительности + на долго ли SSD хватит в таком режиме работы... ... |
|||
:
Нравится:
Не нравится:
|
|||
01.06.2017, 19:31 |
|
Удаление данных в большой таблице
|
|||
---|---|---|---|
#18+
Уважаемый авторПопробуй: 1. Использовать транзакции. (значительно уменьшает время) 2. Сделать бэкап базы, разверни бэкап в in_memory, там удали и скинь назад. Конечно же, использую транзакции. Думаю, что запись 5 гигов из памяти на HDD выйдет еще медленнее. Я сначала подозревал, что проблема может быть в Qt (sqlite используется через нее, а не напрямую). Но я тестировал запросы в двух разных сторонних приложениях, открывая тестовую базу (SQlite Expert, DB Browser for QSlite), и получал похожие результаты. Основной вопрос, который хотелось бы решить - sqlite для таких целей не подходит, либо же проблема у меня (сборка sqlite, сборка Qt, неправильно готовлю БД или сами запросы). ... |
|||
:
Нравится:
Не нравится:
|
|||
02.06.2017, 11:52 |
|
Удаление данных в большой таблице
|
|||
---|---|---|---|
#18+
Lexerys, Проверь PRAGMA параметр auto_vacuum, попробуй выставить NONE, если установлен FULL может тормозить при удалении ... |
|||
:
Нравится:
Не нравится:
|
|||
02.06.2017, 13:04 |
|
Удаление данных в большой таблице
|
|||
---|---|---|---|
#18+
VSVLAD Что-то не верится в увеличении производительности + на долго ли SSD хватит в таком режиме работы... ничего не будет с SSD, это мифы... первые SSD были к этому чувствительны, у меня на MAC Pro молотит уже который год и ничего + на сервере в одной организации под БД SSD стоит, молотит 24 часа в сутки, разумеется бэкапы делаются в другое место. Полет нормальный ... |
|||
:
Нравится:
Не нравится:
|
|||
02.06.2017, 13:07 |
|
Удаление данных в большой таблице
|
|||
---|---|---|---|
#18+
LexerysДумаю, что запись 5 гигов из памяти на HDD выйдет еще медленнее. А ты попробуй... ... |
|||
:
Нравится:
Не нравится:
|
|||
02.06.2017, 13:15 |
|
Удаление данных в большой таблице
|
|||
---|---|---|---|
#18+
Уважаемый авторLexerys, Проверь PRAGMA параметр auto_vacuum, попробуй выставить NONE, если установлен FULL может тормозить при удалении auto_vacuum = NONE Уважаемый авторLexerysДумаю, что запись 5 гигов из памяти на HDD выйдет еще медленнее. А ты попробуй... Не могу я рассчитывать на такое количество оперативы. Опять же, я ничего не требую от sqlite сверх. А то скажете еще - хочу скорости сервера от среднестатистического компа. Не может она - ну и ладно. Но хочется понять, она правда не может, или я неправильно ее готовлю. ... |
|||
:
Нравится:
Не нравится:
|
|||
02.06.2017, 16:52 |
|
Удаление данных в большой таблице
|
|||
---|---|---|---|
#18+
LexerysОпять же, я ничего не требую от sqlite сверх. А то скажете еще - хочу скорости сервера от среднестатистического компа. Не может она - ну и ладно. Но хочется понять, она правда не может, или я неправильно ее готовлю.Возьми стандартную консоль и сделай из нее. ... |
|||
:
Нравится:
Не нравится:
|
|||
02.06.2017, 17:48 |
|
Удаление данных в большой таблице
|
|||
---|---|---|---|
#18+
White OwlLexerysОпять же, я ничего не требую от sqlite сверх. А то скажете еще - хочу скорости сервера от среднестатистического компа. Не может она - ну и ладно. Но хочется понять, она правда не может, или я неправильно ее готовлю.Возьми стандартную консоль и сделай из нее. Скачал последнюю, проверил - точно такие же времена. Все прагмы проверил, установлено, DEBUG - выключен. ... |
|||
:
Нравится:
Не нравится:
|
|||
02.06.2017, 19:04 |
|
Удаление данных в большой таблице
|
|||
---|---|---|---|
#18+
Источник большой задержки при удалении был найден. Таблица на 5 000 000 элементов: Код: sql 1. 2. 3. 4. 5. 6.
Тестовый запрос в консоли sqlite на удаление 5000 элементов (один SERIE_ID => 1000 снимков): Код: sql 1. 2. 3.
Начальная таблица: размер файла 600Мб, удаление выполняется без задержек (несколько миллисекунд). Далее добавляю в таблицу поле UID разными способами: + <UID text unique not null> без индекса => размер фала вырос до 1 Гб, удаление тормозит (~15 с DELETE, ~15 с COMMIT). + <UID text not null> без индекса => 780 Мб, удаление - без задержек. + <UID text not null> с индексом => 1 Гб, удаление тормозит (~15 с DELETE, ~15 с COMMIT). + <UID text primary key> с индексом, но без явного задание ID => 1.2 Гб, удаление тормозит (~15 с DELETE, ~15 с COMMIT). Виноват индекс по текстовому полю, создаваемый вручную или неявно посредством unique. Возможно, кому-то подобное тоже пригодится. Всем спасибо! ... |
|||
:
Нравится:
Не нравится:
|
|||
05.06.2017, 13:48 |
|
|
start [/forum/topic.php?fid=54&msg=39462612&tid=2008501]: |
0ms |
get settings: |
8ms |
get forum list: |
11ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
50ms |
get topic data: |
11ms |
get forum data: |
2ms |
get page messages: |
51ms |
get tp. blocked users: |
1ms |
others: | 280ms |
total: | 420ms |
0 / 0 |