Как удалить тяжелые записи из таблицы наиболее эффективным способом?

Это так: у меня есть таблица с 16 000 строками с дочерней таблицей с 4 000 000 строк. В родительской таблице есть столбец с большим количеством данных (это wkt, используемый для геометрии). Мне нужно периодически очищать данные, и на данный момент мне нужно удалить 5685 родительских строк вместе с 1 400 000 дочерних строк. Я изо всех сил пытаюсь написать наиболее производительный запрос для этого. Мой текущий метод таков:

1) Получите все идентификаторы из родительской таблицы из строк, которые необходимо удалить.

SELECT Id, ValidTo From ParentTable Where ValidTo < someDate;

2) Для каждого идентификатора я выполняю следующие команды:

DELETE FROM ChildTable WHERE ParentId = IdFromStepOne;

DELETE FROM ParentTable WHERE Id = IdFromStepOne

Это займет 15 минут для 95-100 записей, так что это будет сделано за 14 часов .. Можно ли это написать более производительно? Я кодирую в .Net Core и использую Entitiy Framework для вашей информации.

Заранее спасибо!

Какие СУБД вы используете?

jarlh 10.08.2018 09:35

Делайте DELETE в транзакциях разумного размера. Возможно удаление 1000 или 10000 строк за транзакцию.

jarlh 10.08.2018 09:36
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
1
2
43
2

Ответы 2

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

Используйте предложение IN, чтобы выполнить это для нескольких значений.

    DELETE FROM ChildTable WHERE ParentId in (SELECT Id From ParentTable Where ValidTo < someDate)

    DELETE FROM ParentTable WHERE Id in (SELECT Id From ParentTable Where ValidTo < someDate)

Поскольку вам нужно удалить строки в двух таблицах, вам понадобится 2 запроса, и запрос SELECT не должен выбирать столбец ValidTo, а только идентификатор.

Я бы написал такие запросы:

DELETE FROM ChildTable ct
WHERE EXISTS (SELECT pt.Id FROM ParentTable pt WHERE ct.Id_parent = pt.Id AND pt.ValidTo < someDate);

DELETE FROM ParentTable
WHERE ValidTo < someDate;

Используя pl / sql, вы должны иметь возможность выбрать Id из ParentTable для удаления только один раз.

Query1 => SELECT Id FROM ParentTable WHERE ValidTo < someDate
Query2 => DElETE FROM ChildTable WHERE id_parent IN [results of Query 1]
Query3 => DELETE FROM ParentTable WHERE Id IN [results of Query 1]

Достаточно ли производительно использовать подзапрос? Будет ли он проверять каждую запись таблицы (4 000 000) записей для каждой записи?

SanderSoetaert 10.08.2018 10:02

Он будет проверять каждую запись, если у вас нет индекса в столбце ValidTo.

Chocolord 10.08.2018 11:01

У меня есть только индекс в столбце parentId дочерней таблицы

SanderSoetaert 10.08.2018 12:18

Затем запрос, обнаруживающий Id родителей, будет проверять все записи для проверки значения ValidTo, альтернатива pl / sql может помочь, выполнив этот запрос только один раз.

Chocolord 10.08.2018 12:32

Другие вопросы по теме