A melhor maneira de abordar essa pergunta é inserindo os 4 milhões de registros em uma tabela. Na verdade, você pode colocá-los em uma tabela com uma coluna de identidade, "inserindo em massa" em uma exibição.
create table TheIds (rownum int identity(1,1), id int);
create view v_TheIds (select id from TheIds);
bulk insert into v_TheIds . . .
Com todos os dados no banco de dados, agora você tem muito mais opções. Experimente a atualização:
update t
set booleanfield = 1
where exists (select 1 from TheIds where TheIds.id = t.id)
Você também deve criar um índice em
TheIds(id)
. Esta é uma grande atualização, todas executando como uma transação. Isso pode ter implicações de desempenho ruins e começar a preencher o log. Você pode dividi-lo em transações menores usando o
rownum
coluna:update t
set booleanfield = 1
where exists (select 1 from TheIds where TheIds.id = t.id and TheIds.rownum < 1000)
A cláusula existe aqui está fazendo o equivalente ao
left outer join
. A principal diferença é que essa sintaxe de subconsulta correlacionada deve funcionar em outros bancos de dados, onde as junções com atualizações são específicas do banco de dados. Com o
rownum
coluna, você pode selecionar quantas linhas desejar para a atualização. Então, você pode colocar a atualização em um loop, se a atualização geral for muito grande:where rownum < 100000
where rownum between 100000 and 199999
where rownum between 200000 and 299999
e assim por diante. Você não precisa fazer isso, mas pode se quiser agrupar as atualizações por algum motivo.
A ideia principal é colocar a lista de ids em uma tabela no banco de dados, para que você possa usar o poder do banco de dados para as operações subsequentes.