Гость
Форумы / SQLite [игнор отключен] [закрыт для гостей] / Удаление данных в большой таблице / 15 сообщений из 15, страница 1 из 1
30.05.2017, 17:18
    #39462556
Lexerys
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Удаление данных в большой таблице
Здравствуйте!

Использую 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.
CREATE TABLE IF NOT EXISTS SERIE (
	ID integer primary key autoincrement,
	UID text unique not null,
        ... и еще 5 text полей и 5 int полей, без индексов
);
CREATE INDEX IF NOT EXISTS SERIEUID_INDEX ON SERIE (UID);

CREATE TABLE IF NOT EXISTS IMAGE (
	ID integer primary key autoincrement,
	UID text unique not null,
	SERIE_ID int,
        ... и еще 5 text полей и 5 int полей, без индексов
	FOREIGN KEY(SERIE_ID) REFERENCES SERIE(ID));
CREATE INDEX IF NOT EXISTS SERIEID_INDEX ON IMAGE(SERIE_ID);


Одному SERIE_ID соответствуют 5000 записей в таблице IMAGE со ссылкой на этот ID (который указан в качестве FOREIGN KEY).

Количество записей в таблице SERIE ~ 50 000, IMAGE ~ 250 000 000.

Вот такой запрос выполняется мгновенно:
Код: sql
1.
2.
3.
BEGIN;
SELECT ID FROM DCM_IMAGE WHERE SERIE_ID IN (тут десять ID из таблицы);
COMMIT;


А собственно удаление занимает на SSD 2 секунды, на обычном HDD - около минуты.
Код: sql
1.
2.
3.
BEGIN;
DELETE FROM DCM_IMAGE WHERE SERIE_ID IN (тут десять ID из таблицы);
COMMIT;


Тестировал эти запросы в своем приложении, и в паре сторонних утилит (SQlite Expert, DB Browser for QSlite), времена везде примерно одинаковы.

Настройки базы и соединения:
Код: sql
1.
2.
3.
4.
5.
6.
"PRAGMA page_size = 4096;"
"PRAGMA cache_size = 16384;"
"PRAGMA wal_autocheckpoint = 5000"
"PRAGMA synchronous = NORMAL;"
"PRAGMA temp_store = MEMORY;"
"PRAGMA journal_mode = WAL;"



Собственно, вопрос: можно ли существенно улучшить время удаления, или это тупик для qslite?
Как еще можно организовать логику, когда удаление большой пачки снимков периодически требуется, но минута - это недопустимо много?
Спасибо.
...
Рейтинг: 0 / 0
30.05.2017, 18:16
    #39462612
White Owl
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Удаление данных в большой таблице
http://sqlite.org/wal.html
Обрати внимание на девятый пункт "против".

LexerysКак еще можно организовать логику, когда удаление большой пачки снимков периодически требуется, но минута - это недопустимо много?Вместо удаления, можно просто помечать запись как "больше не играть". Просто добавь в таблицу поле "Expiration_Date null" и если оно пусто - запись рабочая, если не пустая, то считать ее удаленной.
Это заодно позволит смотреть историю, типа вчера были такие записи, а сегодня сякие.
...
Рейтинг: 0 / 0
30.05.2017, 18:31
    #39462623
Lexerys
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Удаление данных в большой таблице
White Owl http://sqlite.org/wal.html
Обрати внимание на девятый пункт "против".
Размер транзакции не слишком велик. Впрочем, я попробовал разные режимы журнала - никакой разницы в скорости.

White OwlВместо удаления, можно просто помечать запись как "больше не играть". Просто добавь в таблицу поле "Expiration_Date null" и если оно пусто - запись рабочая, если не пустая, то считать ее удаленной.
Это заодно позволит смотреть историю, типа вчера были такие записи, а сегодня сякие.
Над этим вариантом тоже думал. Но тут либо размер файла базы будет постепенно расти, либо нужно предусматривать периодически запускаемую процедуру удаления помеченных записей, и оба варианта не очень нравятся. Хотя предполагаю, что придется остановиться на первом.

Попробовал подобный запрос с удалением такого же числа записей в firebird, с подобной таблицей, там все удалилось за 200ms (вместо 1000ms sqlite).
...
Рейтинг: 0 / 0
30.05.2017, 18:48
    #39462628
White Owl
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Удаление данных в большой таблице
Ну вообще-то, та версия что с Qt идет уже оооооочень старая. 3.8.6 против сегодняшней 3.19.2.
Скачай амальгаму свежей версии, замени файлы в %Qt%\Src\qtbase\src\3rdparty\sqlite\ на свежие, и пересобери qsqlite плагин в %Qt%\Src\qtbase\src\plugins\sqldrivers\sqlite\
Точно избавишься от много-летних багов.
...
Рейтинг: 0 / 0
30.05.2017, 19:28
    #39462645
Lexerys
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Удаление данных в большой таблице
White OwlНу вообще-то, та версия что с Qt идет уже оооооочень старая
Спасибо за замечание, обновил, на скорость удаления это не повлияло. Но все равно полезно =)
...
Рейтинг: 0 / 0
01.06.2017, 17:00
    #39463994
Уважаемый автор
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Удаление данных в большой таблице
Lexerys,

Попробуй:
1. Использовать транзакции. (значительно уменьшает время)
2. Сделать бэкап базы, разверни бэкап в in_memory, там удали и скинь назад.
...
Рейтинг: 0 / 0
01.06.2017, 19:31
    #39464077
VSVLAD
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Удаление данных в большой таблице
Уважаемый автор,

Lexerys(размер файла ~ 5Гб).
Уважаемый авторразверни бэкап в in_memory, там удали и скинь назад

Что-то не верится в увеличении производительности + на долго ли SSD хватит в таком режиме работы...
...
Рейтинг: 0 / 0
02.06.2017, 11:52
    #39464484
Lexerys
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Удаление данных в большой таблице
Уважаемый авторПопробуй:
1. Использовать транзакции. (значительно уменьшает время)
2. Сделать бэкап базы, разверни бэкап в in_memory, там удали и скинь назад.

Конечно же, использую транзакции.
Думаю, что запись 5 гигов из памяти на HDD выйдет еще медленнее.

Я сначала подозревал, что проблема может быть в Qt (sqlite используется через нее, а не напрямую).
Но я тестировал запросы в двух разных сторонних приложениях, открывая тестовую базу (SQlite Expert, DB Browser for QSlite), и получал похожие результаты.

Основной вопрос, который хотелось бы решить - sqlite для таких целей не подходит, либо же проблема у меня (сборка sqlite, сборка Qt, неправильно готовлю БД или сами запросы).
...
Рейтинг: 0 / 0
02.06.2017, 13:04
    #39464605
Уважаемый автор
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Удаление данных в большой таблице
Lexerys,
Проверь PRAGMA параметр auto_vacuum, попробуй выставить NONE, если установлен FULL может тормозить при удалении
...
Рейтинг: 0 / 0
02.06.2017, 13:07
    #39464611
Уважаемый автор
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Удаление данных в большой таблице
VSVLAD
Что-то не верится в увеличении производительности + на долго ли SSD хватит в таком режиме работы...

ничего не будет с SSD, это мифы... первые SSD были к этому чувствительны, у меня на MAC Pro молотит уже который год и ничего + на сервере в одной организации под БД SSD стоит, молотит 24 часа в сутки, разумеется бэкапы делаются в другое место.
Полет нормальный
...
Рейтинг: 0 / 0
02.06.2017, 13:15
    #39464620
Уважаемый автор
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Удаление данных в большой таблице
LexerysДумаю, что запись 5 гигов из памяти на HDD выйдет еще медленнее.


А ты попробуй...
...
Рейтинг: 0 / 0
02.06.2017, 16:52
    #39464865
Lexerys
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Удаление данных в большой таблице
Уважаемый авторLexerys,
Проверь PRAGMA параметр auto_vacuum, попробуй выставить NONE, если установлен FULL может тормозить при удалении
auto_vacuum = NONE

Уважаемый авторLexerysДумаю, что запись 5 гигов из памяти на HDD выйдет еще медленнее.

А ты попробуй...
Не могу я рассчитывать на такое количество оперативы.
Опять же, я ничего не требую от sqlite сверх. А то скажете еще - хочу скорости сервера от среднестатистического компа. Не может она - ну и ладно. Но хочется понять, она правда не может, или я неправильно ее готовлю.
...
Рейтинг: 0 / 0
02.06.2017, 17:48
    #39464919
White Owl
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Удаление данных в большой таблице
LexerysОпять же, я ничего не требую от sqlite сверх. А то скажете еще - хочу скорости сервера от среднестатистического компа. Не может она - ну и ладно. Но хочется понять, она правда не может, или я неправильно ее готовлю.Возьми стандартную консоль и сделай из нее.
...
Рейтинг: 0 / 0
02.06.2017, 19:04
    #39464962
Lexerys
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Удаление данных в большой таблице
White OwlLexerysОпять же, я ничего не требую от sqlite сверх. А то скажете еще - хочу скорости сервера от среднестатистического компа. Не может она - ну и ладно. Но хочется понять, она правда не может, или я неправильно ее готовлю.Возьми стандартную консоль и сделай из нее.

Скачал последнюю, проверил - точно такие же времена.
Все прагмы проверил, установлено, DEBUG - выключен.
...
Рейтинг: 0 / 0
05.06.2017, 13:48
    #39465858
Lexerys
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Удаление данных в большой таблице
Источник большой задержки при удалении был найден.

Таблица на 5 000 000 элементов:
Код: sql
1.
2.
3.
4.
5.
6.
CREATE TABLE IF NOT EXISTS IMAGES (
        ID integer primary key autoincrement,
	SERIE_ID int,
	text, text, text, text, text, int, int, int, int, int, int
);
CREATE INDEX IF NOT EXISTS SERIE_ID_INDEX ON IMAGES(SERIE_ID);


Тестовый запрос в консоли sqlite на удаление 5000 элементов (один SERIE_ID => 1000 снимков):
Код: sql
1.
2.
3.
BEGIN;
DELETE FROM IMAGES WHERE SERIE_ID > 1000 AND SERIE_ID < 1006;
COMMIT;



Начальная таблица: размер файла 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.
Возможно, кому-то подобное тоже пригодится.

Всем спасибо!
...
Рейтинг: 0 / 0
Форумы / SQLite [игнор отключен] [закрыт для гостей] / Удаление данных в большой таблице / 15 сообщений из 15, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]