Это так: у меня есть таблица с 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 для вашей информации.
Заранее спасибо!
Делайте DELETE в транзакциях разумного размера. Возможно удаление 1000 или 10000 строк за транзакцию.


Ваш запрос показывает, что вы перебираете каждый идентификатор и удаляете дочерние и родительские строки.
Используйте предложение 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) записей для каждой записи?
Он будет проверять каждую запись, если у вас нет индекса в столбце ValidTo.
У меня есть только индекс в столбце parentId дочерней таблицы
Затем запрос, обнаруживающий Id родителей, будет проверять все записи для проверки значения ValidTo, альтернатива pl / sql может помочь, выполнив этот запрос только один раз.
Какие СУБД вы используете?