Re: [oracle_br] Re: UPDATE em milhoes de registros
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
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
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
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!