Вы удаляете большое количество строк. Это проблема. В удалениях много накладных расходов.
Если вы удаляете значительное количество строк в таблице - и значимое может составлять всего несколько процентов - тогда часто быстрее воссоздать таблицу:
select b.*
into temp_b -- actually, I wouldn't use a temporary table in case the server goes down
from b
where b.id = (select max(a.id) from b b2 where b2.id = b.a_id);
truncate table b;
insert into b
select *
from temp_b;
Прежде чем пытаться это сделать, убедитесь, что вы создали резервную копию b
или, по крайней мере, спрятали ее копию где-то.
Обратите внимание, что я изменил структуру NOT IN
. Я настоятельно не рекомендую использовать NOT IN
, потому что семантика не интуитивна, когда подзапрос возвращает значения NULL
. Если бы существовало только одно значение NULL
, то WHERE
никогда не получило бы значение ИСТИНА. Даже если значения NULL
не являются проблемой в этом случае, я настоятельно рекомендую использовать другие альтернативы, чтобы у вас не возникало проблем, когда возможны NULL
s.
Для производительности на SELECT
требуется индекс на b(a_id, id)
. Вы можете обнаружить, что такой индекс помогает в исходном запросе.