#performance #sqlite #sql-delete
#Производительность #sqlite #sql-delete
Вопрос:
У меня есть база данных SQLite (первый проект с SQLite), где мне нужно удалить сразу большую часть записей, это примерно 14 000 записей. Запрос выглядит следующим образом (я изменил имена для лучшего чтения) :
delete from table_1 where table_2_id in (
select id from table_2 where table_3_id in (
select id from table_3
where (deleted = 1 or
table_4_id in (select id from table_4 where deleted = 1))));
Удаление этого запроса занимает около 8 минут. Но когда я делаю
select * from table_1 where table_2_id in (
select id from table_2 where table_3_id in (
select id from table_3
where (deleted = 1 or
table_4_id in (select id from table_4 where deleted = 1))));
это дает мне результат за 3 секунды.
Я пытался использовать транзакцию, размер кэша, режим журнала, но я не могу заставить его работать, чтобы повысить производительность. Чего мне не хватает?
Комментарии:
1. Создайте временную таблицу (
CREATE TEMP TABLE to_delete AS select table_1_id FROM table1 ...
); как быстро выполняется удаление с помощью этого (delete from table_1 where table_1_id in to_delete
)?2. Спасибо за быстрый ответ. Для создания временной таблицы потребовалось менее секунды, поэтому кажется, что производительность правильная. Чтобы удалить конкретные данные с помощью запроса «удалить из таблицы_1, где table_1_id в (выберите идентификатор из to_delete)», это снова займет около 8 минут.
3. Насколько велик файл базы данных? Сколько у вас памяти? Какая файловая система? Сеть?
4. В настоящее время у меня есть следующие спецификации: Размер = 30 МБ, Память: 8 ГБ, диск: SSD, Система: Windows 7, Сеть: локальное хранилище
5. 30 МБ? Не ГБ? У вас есть сканер вирусов?
Ответ №1:
У меня была та же проблема. Решение состояло в том, чтобы разделить его на множество меньших фрагментов и делать это снова и снова, пока не будет затронуто больше строк (sqlite3_changes() возвращает ноль).
Конечно, таким образом операция не завершается раньше, но таблица не блокируется слишком долго непрерывно. Надеюсь, это кому-то поможет.
Ответ №2:
Это было 30 МБ, а также отключило сканер вирусов, но без какого-либо результата. Итак, я попробовал несколько способов, скопировал базу данных, удалил все внешние ключи и повторил попытку, и это было намного быстрее. Итак, затем я поместил индекс для всех внешних ключей, и он также быстро удалялся. Итак, это было решение, но я не знаю, почему оно затем выбирает fast и удаляет super slow. Но надеюсь, что это кому-нибудь поможет!
Ответ №3:
Есть ли у вас индекс для какого-либо из задействованных столбцов? Если это так, подумайте о том, чтобы удалить его для большого удаления, а затем перестроить его. Если вы этого не сделаете, попробуйте добавить его.
Ответ №4:
У меня есть скрипт на python для удаления записей в базе данных SQLite, lfl — это список файлов, которые я хочу удалить из базы данных, в заявлении значительно ускоряется процесс:
while len(lfl)>0:
print ("Deleting entries in DB: ",len(lfl))
sql="""delete from md5t where file in ('%s')"""%('',''.join(tuple(lfl[:500])))
cursor.execute(sql)
db.commit()
del lfl[:500]