Atualizando 700 milhões de linhas para o mesmo valor


12

Eu tenho um data warehouse (oracle) em que preciso definir uma coluna com o mesmo valor para todos os 700 milhões de linhas.

Eu não tenho acesso de administrador ou acesso a um administrador, portanto, isso precisa ser realizado com sql básico e nenhuma tabela temporária é criada.

Para complicar ainda mais, se eu tentar apenas fazer uma atualização simples em que 1 = 1, ela ficará sem espaço para refazer.

O jeito que eu estou executando agora é um loop como este:

loop
  update mytable set mycolumn = '1' where mycolumn is null and rownum < 50000;
  commit;
end loop

mas sei que isso é provavelmente ingênuo e deve haver uma solução mais rápida e elegante.


A tabela está particionada?
Jack diz que tente topanswers.xyz 30/08

Eu não acredito nisso. Existem alguns índices, mas nenhum deles envolve a coluna que estou atualizando.
owook

Respostas:


4

Se você tiver espaço, poderá CTAS usando o mínimo de desfazer / refazer . Se você tiver algum índice, fazê-lo de qualquer outra maneira será muito lento e gerará log como um louco.

No caso de você ter uma única IOT sem índices secundários ou um único cluster de tabela, você pode percorrer a atualização da chave primária / de cluster em blocos sem precisar redigitalizar a tabela inteira para localizar os campos que ainda não foram atualizados.

--editar

Não consigo criar uma tabela secundária ... Existem alguns índices, mas nenhum deles envolve a coluna que estou atualizando.

Então, sugiro que divida a tabela em partes para processamento usando algo que você está indexando (mesmo que seja uma coluna única, você pode dividi-la em intervalos de valores). código. Você terá que conviver com uma grande quantidade de refazer e também limpará seu espaço de desfazer (portanto, nenhum flashback posteriormente)

--edit2

se você pode adicionar / renomear / soltar colunas, você pode fazer isso com muita eficiência , mas apenas no 11g


1
Se o seu DBA permitir NOLOGGING, isso invalidará os hotstandbys.
Gaius

Na verdade, e um backup depois seria uma boa idéia também - mas este é um armazém e nologgingé uma ferramenta para armazéns
Jack diz tentar topanswers.xyz

Não consigo criar uma tabela secundária, certamente não tão grande quanto a primeira, mesmo que seja apenas temporária.
Owook 30/08/11

Seu link de 11g parecia promissor, mas vejo comentários de que uma tabela de 60m ainda era terrivelmente lenta por ter que definir o valor para cada linha. Como minha tabela tem 10 vezes esse tamanho, esse método pode não ser uma melhoria.
Owook 31/08/19

@owook não, no 11g esta operação é rápida e não define o valor para cada linha "para alguns tipos de tabelas (por exemplo, tabelas sem colunas LOB)" . Experimente em um subconjunto da sua tabela ( create table foo as select * from bar where rownum<100000)
Jack diz que tente topanswers.xyz 31/08

1

Se você usa 11g, solte a coluna e adicione-a novamente como uma coluna NOT NULL com um valor padrão. Isso é contra-intuitivo, mas o Oracle armazenará o valor padrão na definição da tabela, substituindo o valor padrão no tempo de execução.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.