Re: [oracle_br] Re: UPDATE em milhoes de registros

2010-07-14 Por tôpico Samuel Corradi
Obrigado pelas dicas Chiappa!




Em 14-07-2010 09:47, José Laurindo escreveu:
   Paera encerrar, uma dica : pra qquer um que esteja tentando entender os 
 conceitos e formas de uso (Eficiente!) de databases Oracle eu ** 
 enfaticamente ** Recomendo o livro Expert Oracle Database Architecture: 9i 
 and 10g Programming Techniques and Solutions, de Thomas Kyte : junto dele 
 vem em CD-ROM a versão anterior, que trata de conceitos mais básicos, chamada 
 Expert One on One: Oracle - uma leitura e estudio Cuidadosos desses dois 
 vão te dar uma visão Radicalmente diferente do banco de dados Oracle e suas 
 possibilidades/funcionalidades, eu garanto...



Re: [oracle_br] Re: UPDATE em milhoes de registros

2010-07-13 Por tôpico Samuel Corradi
Mas como fazer esse comando em um update soh?

Voce diz tirar o coteudo do loop e colocar em um UPDATE que NAO tenha a 
clausula WHERE?

-
...
LOOP

codigo := TRIM(SUBSTR(registro.f14, INSTR(registro.f14,'-',-1) + 2, 
LENGTH(registro.f14)));

nome := TRIM(SUBSTR(registro.f14, 1, INSTR(registro.f14,'-',-1) - 2 ));

UPDATE sadig.mod0046 SET f14=nome || '[' || codigo || ']' WHERE 
f1=registro.f1 and f6=registro.f6;

END LOOP;
...
-

para

-

UPDATE sadig.mod0046
SET f14=TRIM(SUBSTR(f14, 1, INSTR(f14,'-',-1) - 2 )) || '[' || 
TRIM(SUBSTR(f14, INSTR(f14,'-',-1) + 2, LENGTH(f14))) || ']';

-


Em 12-07-2010 14:54, José Laurindo escreveu:
 Oi, Samuel : primeiro de tudo, rigorosamente Não Existe isso de o script 
 parar quando redo log file enche : o que pode acontecer nesse sentido é , se 
 o banco est;a programado para arquivar/copiar os redo log files cheios 
 (archive mode) E não há espaço em disco não é a sessão, mas sim o banco 
 TODINHO que para - isso é Bem difícil de acontecer, mas o seu DBA é 
 Totalmente capaz de solucionar isso, uma mensagem BEM ESPECÍFICA é gerada no 
 alert do banco quando isso ocorre... COnsulte o seu DBA pra que isso seja 
 verificado.
   Caso não seja esse o caso, aí pra mim o que está acontecendo é simples (e 
 esperada) ** LENTIDÃO ** por causa da (via de regra totalmente INAPROPRIADA) 
 programação e processamento uma iinha/registro por vez que vc está fazendo 
 (também conhecida como row-by-row, oo slow-by-slow, slow aqui por motivos 
 óbvios)...
Se vc quer performance máxima num SQL, dê os recursos necessários e deixa 
 o banco trabalhar : isso implicaria num primiro momento em acionar o DBA, 
 para que ele crie área de rollback/undo suficiente e (se adequado) ative 
 paralelismo e (se possível) desative eventuais triggers e índices (com 
 REBUILD em modo NOLOGGING posterior), E no segundo passo vc JOGA FORA esse 
 loop e faz o comando num UPDATE só, esse é o mantra, é o caminho, é a Melhor 
 Coisa quando vc quer máxima performance num SQL...
   Dá uma pesquisada em http://asktom.oracle.com por SQL ROW BY ROW 
 PERFORMANCE que vc acha várias refs e dicas sobre isso...

   []s

 Chiappa


 --- Em oracle_br@yahoogrupos.com.br, Samuel Corradicorrad...@...  escreveu

 Ola pessoal!

 Tenho que faz update em um campo do tipo VARCHAR2.

 Para isso fiz um PL que abre um cursor e percorrer todas linhas
 alterando os valores.

 Agora, estou tendo um problema durante a atualizacao. Aparentemente, os
 redo logs enchem e o sript para. Nao sei dizer exatamente o que estah
 acontecendo, mas acredito que tenho que fazer um controle maior durante
 esse update.

 Alguem tem alguma sugestao do que pode estar acontecendo? Alguem jah
 passou por esse trabalho de atualizar muitos registros de uma tabela?

 Segue meu PL para referencia:

 

 DECLARE
 CURSOR c1 IS select * from sadig.mod0046;
 flag BOOLEAN DEFAULT false;
 tamanho PLS_INTEGER DEFAULT 0;
 codigo VARCHAR2(45);
 nome VARCHAR2(85);
 BEGIN
  FOR registro IN C1
  LOOP
  codigo := TRIM(SUBSTR(registro.f14, INSTR(registro.f14,'-',-1) 
 + 2,
 LENGTH(registro.f14)));
  nome := TRIM(SUBSTR(registro.f14, 1, INSTR(registro.f14,'-',-1) 
 - 2 ));
  UPDATE sadig.mod0046 SET f14=nome || '[' || codigo || ']' WHERE
 f1=registro.f1 and f6=registro.f6;
  END LOOP;
 END;

 =

 Obrigado!







Re: [oracle_br] Re: UPDATE em milhoes de registros

2010-07-13 Por tôpico Samuel Corradi
Ok. Nao sei se desativar eh uma boa. A pergunta nesse ponto eh: Se todos 
serao atualizado, o indice nao tera que ser recriado de qualquer forma?? 
Ou o indice soh eh reriado com mudancas na estrutura da tabela?

Outra duvida, o que eh esse paralelismo? Qual o conceito disso? Como uso?

Sobre a UNDO, vou criar um datafile maior antes de fazer essa 
operacao... (Sim, o DBA sou eu mesmo. rsrs)





Em 13-07-2010 16:16, José Laurindo escreveu:
 Sim, pelo que eu entendi vc quer mesmo trabalhar na tabela inteira ( o WHERE 
 é só pra indicar o último registro lido, mas TODOS os registros tem que ser 
 lidos e atualizados pelo que entendi), então sim, vc teria um único UPDATE 
 sem WHERE - apenas, torno a repetir, ANTES DE FAZER ISSo acione o seu DBA 
 para que ele crie uma área de undo/rollback apropriada, ative paralelismo no 
 acesso à essa tabela, avalie se vale a pena desativar o índice e depois fazer 
 o rebuild em NOLOGGING, enfim...

   []s

 Chiappa

 --- Em oracle_br@yahoogrupos.com.br, Samuel Corradicorrad...@...  escreveu

 Mas como fazer esse comando em um update soh?

 Voce diz tirar o coteudo do loop e colocar em um UPDATE que NAO tenha a
 clausula WHERE?

 -
 ...
 LOOP

 codigo := TRIM(SUBSTR(registro.f14, INSTR(registro.f14,'-',-1) + 2,
 LENGTH(registro.f14)));

 nome := TRIM(SUBSTR(registro.f14, 1, INSTR(registro.f14,'-',-1) - 2 ));

 UPDATE sadig.mod0046 SET f14=nome || '[' || codigo || ']' WHERE
 f1=registro.f1 and f6=registro.f6;

 END LOOP;
 ...
 -

 para

 -

 UPDATE sadig.mod0046
 SET f14=TRIM(SUBSTR(f14, 1, INSTR(f14,'-',-1) - 2 )) || '[' ||
 TRIM(SUBSTR(f14, INSTR(f14,'-',-1) + 2, LENGTH(f14))) || ']';

 -


 Em 12-07-2010 14:54, José Laurindo escreveu:
 Oi, Samuel : primeiro de tudo, rigorosamente Não Existe isso de o script 
 parar quando redo log file enche : o que pode acontecer nesse sentido é , 
 se o banco est;a programado para arquivar/copiar os redo log files cheios 
 (archive mode) E não há espaço em disco não é a sessão, mas sim o banco 
 TODINHO que para - isso é Bem difícil de acontecer, mas o seu DBA é 
 Totalmente capaz de solucionar isso, uma mensagem BEM ESPECÍFICA é gerada 
 no alert do banco quando isso ocorre... COnsulte o seu DBA pra que isso 
 seja verificado.
Caso não seja esse o caso, aí pra mim o que está acontecendo é simples 
 (e esperada) ** LENTIDÃO ** por causa da (via de regra totalmente 
 INAPROPRIADA) programação e processamento uma iinha/registro por vez que vc 
 está fazendo (também conhecida como row-by-row, oo slow-by-slow, slow aqui 
 por motivos óbvios)...
 Se vc quer performance máxima num SQL, dê os recursos necessários e 
 deixa o banco trabalhar : isso implicaria num primiro momento em acionar o 
 DBA, para que ele crie área de rollback/undo suficiente e (se adequado) 
 ative paralelismo e (se possível) desative eventuais triggers e índices 
 (com REBUILD em modo NOLOGGING posterior), E no segundo passo vc JOGA FORA 
 esse loop e faz o comando num UPDATE só, esse é o mantra, é o caminho, é a 
 Melhor Coisa quando vc quer máxima performance num SQL...
Dá uma pesquisada em http://asktom.oracle.com por SQL ROW BY ROW 
 PERFORMANCE que vc acha várias refs e dicas sobre isso...

[]s

  Chiappa


 --- Em oracle_br@yahoogrupos.com.br, Samuel Corradicorradibh@   escreveu

 Ola pessoal!

 Tenho que faz update em um campo do tipo VARCHAR2.

 Para isso fiz um PL que abre um cursor e percorrer todas linhas
 alterando os valores.

 Agora, estou tendo um problema durante a atualizacao. Aparentemente, os
 redo logs enchem e o sript para. Nao sei dizer exatamente o que estah
 acontecendo, mas acredito que tenho que fazer um controle maior durante
 esse update.

 Alguem tem alguma sugestao do que pode estar acontecendo? Alguem jah
 passou por esse trabalho de atualizar muitos registros de uma tabela?

 Segue meu PL para referencia:

 

 DECLARE
 CURSOR c1 IS select * from sadig.mod0046;
 flag BOOLEAN DEFAULT false;
 tamanho PLS_INTEGER DEFAULT 0;
 codigo VARCHAR2(45);
 nome VARCHAR2(85);
 BEGIN
FOR registro IN C1
LOOP
codigo := TRIM(SUBSTR(registro.f14, INSTR(registro.f14,'-',-1) 
 + 2,
 LENGTH(registro.f14)));
nome := TRIM(SUBSTR(registro.f14, 1, INSTR(registro.f14,'-',-1) 
 - 2 ));
UPDATE sadig.mod0046 SET f14=nome || '[' || codigo || ']' WHERE
 f1=registro.f1 and f6=registro.f6;
END LOOP;
 END;

 =

 Obrigado!











Re: [oracle_br] Re: UPDATE em milhoes de registros

2010-07-12 Por tôpico Samuel Corradi
Valew Chiappa! Eu nao vi o erro apresentado pelo Oracle. Mas tenho 
certeza que o banco nao parou pq quem viu o erro nao teria como volta-lo 
rsrs Nao sei exatamento o que houver.

Vou seguir o conselho do Raul e do Eduardo Amaral em comitar a cada 1000 
registros.

Vamos ver o que acontece





Em 12-07-2010 14:54, José Laurindo escreveu:
 Oi, Samuel : primeiro de tudo, rigorosamente Não Existe isso de o script 
 parar quando redo log file enche : o que pode acontecer nesse sentido é , se 
 o banco est;a programado para arquivar/copiar os redo log files cheios 
 (archive mode) E não há espaço em disco não é a sessão, mas sim o banco 
 TODINHO que para - isso é Bem difícil de acontecer, mas o seu DBA é 
 Totalmente capaz de solucionar isso, uma mensagem BEM ESPECÍFICA é gerada no 
 alert do banco quando isso ocorre... COnsulte o seu DBA pra que isso seja 
 verificado.
   Caso não seja esse o caso, aí pra mim o que está acontecendo é simples (e 
 esperada) ** LENTIDÃO ** por causa da (via de regra totalmente INAPROPRIADA) 
 programação e processamento uma iinha/registro por vez que vc está fazendo 
 (também conhecida como row-by-row, oo slow-by-slow, slow aqui por motivos 
 óbvios)...
Se vc quer performance máxima num SQL, dê os recursos necessários e deixa 
 o banco trabalhar : isso implicaria num primiro momento em acionar o DBA, 
 para que ele crie área de rollback/undo suficiente e (se adequado) ative 
 paralelismo e (se possível) desative eventuais triggers e índices (com 
 REBUILD em modo NOLOGGING posterior), E no segundo passo vc JOGA FORA esse 
 loop e faz o comando num UPDATE só, esse é o mantra, é o caminho, é a Melhor 
 Coisa quando vc quer máxima performance num SQL...
   Dá uma pesquisada em http://asktom.oracle.com por SQL ROW BY ROW 
 PERFORMANCE que vc acha várias refs e dicas sobre isso...

   []s

 Chiappa


 --- Em oracle_br@yahoogrupos.com.br, Samuel Corradicorrad...@...  escreveu

 Ola pessoal!

 Tenho que faz update em um campo do tipo VARCHAR2.

 Para isso fiz um PL que abre um cursor e percorrer todas linhas
 alterando os valores.

 Agora, estou tendo um problema durante a atualizacao. Aparentemente, os
 redo logs enchem e o sript para. Nao sei dizer exatamente o que estah
 acontecendo, mas acredito que tenho que fazer um controle maior durante
 esse update.

 Alguem tem alguma sugestao do que pode estar acontecendo? Alguem jah
 passou por esse trabalho de atualizar muitos registros de uma tabela?

 Segue meu PL para referencia:

 

 DECLARE
 CURSOR c1 IS select * from sadig.mod0046;
 flag BOOLEAN DEFAULT false;
 tamanho PLS_INTEGER DEFAULT 0;
 codigo VARCHAR2(45);
 nome VARCHAR2(85);
 BEGIN
  FOR registro IN C1
  LOOP
  codigo := TRIM(SUBSTR(registro.f14, INSTR(registro.f14,'-',-1) 
 + 2,
 LENGTH(registro.f14)));
  nome := TRIM(SUBSTR(registro.f14, 1, INSTR(registro.f14,'-',-1) 
 - 2 ));
  UPDATE sadig.mod0046 SET f14=nome || '[' || codigo || ']' WHERE
 f1=registro.f1 and f6=registro.f6;
  END LOOP;
 END;

 =

 Obrigado!