Безопасный подход для больших таблиц:
create unlogged table list_for_delete (id int);
insert into list_for_delete values ....
with to_rm as (
select id from list_for_delete limit 10000
), rm as (
delete from list_for_delete where id in (select id from to_rm)
)
delete from tablename where id in (select id from to_rm);
vacuum analyze tablename;
drop table list_for_delete ;
cte с delete повторять пока не будет affeted rows = 0. Смотреть на лаг репликации, добавлять задержки между запросами и увеличивать/уменьшать размер пачки в зависимости от влияния на прод.
vacuum в конце, можно после половины пройтись дополнительно. С таким-то объёмом можно руками вакуум вообще не делать и оставить автовакууму. А для таблиц побольше при массовом изменении имеет смысл.