|
удалить записи по условию подзапроса - оооочень долго делается. Неужели никак не оптимизи?
|
|||
---|---|---|---|
#18+
Есть такой несложный запросец, который должен удалить все проводки (журнал OPERS) товара с ID товара (MODID), который был внесен в журнал OPERS по накладным с номерами 35333003 и 35332003 ( ORDERS связан с OPERS по связке 2-х полей, которые указаны в запросе). Подзапрос содержит список из около 4,5 тыс. MODID, которые integer. Журнал OPERS не имеет индекса по MODID и соответственно полностью сканируется вся таблица (ну пусть 3 млн. операций). Код: sql 1. 2. 3. 4. 5. 6.
Потом также надо удалить все эти MODID из журнала остатков, и самого справочника товаров (просто меняем в операторе DELETE названия таблиц). А теперь собственно вопрос - запросы выполнялся на отдельном неслабом серваке HP 1,5 суток и так и не завершился, пришлось грохать сам FB через процессы. Проц был загружен файрбердом на одно ядро (установка FB с умолчательными параметрами), потребление оперативы - около 45 МБ (при физических 16 гигах). Быстрая SSD и никаких других задач на серваке. Версия FB 3.0.4, база размером 1,4 ГБ, при выполнении запроса размер заметно не меняла. Читал, что нежелательность использования IN, ну а как еще по-другому можно выбрать условие для удаления? Может, копать в сторону применения подзапроса с CTE? План, который предполагается для выполнения запроса: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16.
... |
|||
:
Нравится:
Не нравится:
|
|||
01.06.2020, 23:23 |
|
удалить записи по условию подзапроса - оооочень долго делается. Неужели никак не оптимизи?
|
|||
---|---|---|---|
#18+
GrigoriyFomin Подзапрос содержит список из около 4,5 тыс. MODID, которые integer. Журнал OPERS не имеет индекса по MODID и соответственно полностью сканируется вся таблица (ну пусть 3 млн. операций). Полный скан будет по количеству возвращенных MODID, т.е. 4,5тыс * кол-во строк в OPERS. ~12 млрд. фетчей. Если создать индекс по modid (это всего одно сканирование таблицы OPERS), то запрос все равно не будет использовать индекс т.к. возвращаемый из подзапроса MODID не отсортирован. Если добавить order by modid, тогда оптимизатор может использовать индекс, но не уверен, что оптимизатор так умеет. Точно будет использовать индекс если сделать так: Код: sql 1. 2. 3. 4. 5. 6. 7.
... |
|||
:
Нравится:
Не нравится:
|
|||
01.06.2020, 23:57 |
|
удалить записи по условию подзапроса - оооочень долго делается. Неужели никак не оптимизи?
|
|||
---|---|---|---|
#18+
Sergey A. Volkov, как-то совсем все печально. не могу понять - почему полный скан OPERS занимает столько времени. Полный бэкап базы занимает 2 минуты, рестор - столько же, почему даже при 12-кратном увеличенном скане всех записей это больше суток занимает? откуда такие тормоза? никакого индекса добавлять не буду, так как задача разовая. я вручную быстрее это сделаю, чем сервер. просто непонятно - в чем академическая ошибка? ... |
|||
:
Нравится:
Не нравится:
|
|||
02.06.2020, 01:37 |
|
удалить записи по условию подзапроса - оооочень долго делается. Неужели никак не оптимизи?
|
|||
---|---|---|---|
#18+
GrigoriyFominпочему полный скан OPERS занимает столько времени. нееет. Это не просто полный скан. У вас же план запроса есть. С конца - table opers full scan. То есть, едем по таблице OPERS, и для каждой записи выполняем то, что выше. Вам же Волков написал - подзапрос не коррелирован с внешним запросом, поэтому на каждую запись OPERS подзапрос будет выполнять одно и то же - строить битмап, потом делать джойн, и выдавать 4.5 тыс записей результата. А в OPERS 3млн записей (с ваших слов). Это значит, что 3 миллиона раз конкретная запись проверяется среди 4.5 тыс "записей результата", так еще и для получения "записей результата" нужно действия выполнить. 3млн * 4.5к = 13.5 млрд операций минимум. Сервер просто долбит и долбит то что вы ему сказали, а вы ждете и ждете. GrigoriyFominя вручную быстрее это сделаю, чем сервер Вам опять же посоветовали "перевернуть" подзапрос наружу - 22144082 , выполнится быстрее. Хотя, если не хотите строить индекс, то получится чуть наоборот - снаружи будет результат 4.5к записей, и запрос delete from opers where modid=:modid; выполнится эти самые 4.5к раз. Полностью читая 3млн записей OPERS. Тем не менее, будет не так медленно, как в предыдущем случае. Быстрее будет создать индекс, выполнить тот execute block, и грохнуть индекс, раз вам он так не нравится. ... |
|||
:
Нравится:
Не нравится:
|
|||
02.06.2020, 03:29 |
|
удалить записи по условию подзапроса - оооочень долго делается. Неужели никак не оптимизи?
|
|||
---|---|---|---|
#18+
GrigoriyFominПолный бэкап базы занимает 2 минуты кстати, ну ок. 2 минуты забэкапить 3млн записей - нормально. Но в запросе-то 3 млн записей умножается на 4.5к раз. Тогда 2 минуты умножаем на 4.5к раз. Получается 9000 минут. Это 150 часов. Какую вы задачу задали, то и получаете. ... |
|||
:
Нравится:
Не нравится:
|
|||
02.06.2020, 03:33 |
|
удалить записи по условию подзапроса - оооочень долго делается. Неужели никак не оптимизи?
|
|||
---|---|---|---|
#18+
GrigoriyFomin Читал, что нежелательность использования IN, ну а как еще по-другому можно выбрать условие для удаления? ... |
|||
:
Нравится:
Не нравится:
|
|||
02.06.2020, 15:10 |
|
удалить записи по условию подзапроса - оооочень долго делается. Неужели никак не оптимизи?
|
|||
---|---|---|---|
#18+
courtmerge с delete, если 3-ка Там не из той таблицы удаляется. Posted via ActualForum NNTP Server 1.5 ... |
|||
:
Нравится:
Не нравится:
|
|||
02.06.2020, 15:15 |
|
удалить записи по условию подзапроса - оооочень долго делается. Неужели никак не оптимизи?
|
|||
---|---|---|---|
#18+
Dimitry Sibiryakov courtmerge с delete, если 3-ка Там не из той таблицы удаляется.из какой "не из той" ? Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9.
а может и того проще Код: sql 1. 2. 3. 4. 5.
... |
|||
:
Нравится:
Не нравится:
|
|||
02.06.2020, 15:29 |
|
удалить записи по условию подзапроса - оооочень долго делается. Неужели никак не оптимизи?
|
|||
---|---|---|---|
#18+
courtwhen matched then delete Хм, действительно. Что-то я не так прочитал в доке. Posted via ActualForum NNTP Server 1.5 ... |
|||
:
Нравится:
Не нравится:
|
|||
02.06.2020, 15:35 |
|
удалить записи по условию подзапроса - оооочень долго делается. Неужели никак не оптимизи?
|
|||
---|---|---|---|
#18+
court, ну наконец-то хоть кто-то вспомнил про MERGE ... |
|||
:
Нравится:
Не нравится:
|
|||
02.06.2020, 15:41 |
|
удалить записи по условию подзапроса - оооочень долго делается. Неужели никак не оптимизи?
|
|||
---|---|---|---|
#18+
hvlad, про merge было неожиданно. Но у этого оператора синтаксис - литру надо брать, чтоб победить. какой-то сложный и не интуитивно понятный. По моему вопросу насчет количества обращений к базе - почему СУБД не кэширует результат подзапроса? Разве для каждой итерации надо выполнять подзапрос условия? А если никаких изменений другими пользователями не делалось в базе и не зачем кэш пересчитывать? Вообщем, решил проблему вручную и в лоб - создал временную таблицу с нужными modid и первичным индексом и грохнул журнал операций по вхождению в эту временную таблицу. Запрос отработал за 2 секунды. Невероятно, но факт. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15.
Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.
Код: plaintext 1. 2. 3. 4. 5. 6. 7.
... |
|||
:
Нравится:
Не нравится:
|
|||
02.06.2020, 22:05 |
|
удалить записи по условию подзапроса - оооочень долго делается. Неужели никак не оптимизи?
|
|||
---|---|---|---|
#18+
GrigoriyFomin, Осталось проверить, что будет, если in (select) в исходном запросе заменить на exists(). ... |
|||
:
Нравится:
Не нравится:
|
|||
02.06.2020, 23:59 |
|
удалить записи по условию подзапроса - оооочень долго делается. Неужели никак не оптимизи?
|
|||
---|---|---|---|
#18+
Vlad F, наверное, разница будет нулевая? ... |
|||
:
Нравится:
Не нравится:
|
|||
03.06.2020, 00:41 |
|
|
start [/forum/topic.php?fid=40&msg=39965478&tid=1560339]: |
0ms |
get settings: |
9ms |
get forum list: |
10ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
50ms |
get topic data: |
12ms |
get forum data: |
2ms |
get page messages: |
56ms |
get tp. blocked users: |
1ms |
others: | 15ms |
total: | 161ms |
0 / 0 |