Só pra a adicionar... Este livro do Tom Kyte vai sair nova edição,
adicionando características do 11g.

 

http://www.amazon.com/Expert-Oracle-Database-Architecture-Programming/dp/143
0229462/ref=pd_sim_b_13

 

Até mais,

 

 

  _____  

De: oracle_br@yahoogrupos.com.br [mailto:oracle...@yahoogrupos.com.br] Em
nome de José Laurindo
Enviada em: quarta-feira, 14 de julho de 2010 09:48
Para: oracle_br@yahoogrupos.com.br
Assunto: [oracle_br] Re: UPDATE em milhoes de registros

 

  

Bom, a gente responde, o forum server pra isso, mas ** FATALMENTE ** vc vai
precisar de um update aí no seu conhecimento pra poder atuar como DBA, não
dá pra ira até os detalhes necessários de implementação aqui no fórum, nem é
a proposta...
Bom, no caso dos índices o que ocorre é que , se vc os desativar durante o
DML que não precisa dele (ie, DNL que atuará na tabela toda e portanto terá
mesmo que fazer um full table scan) , após o DML vc pode pedir pro banco o
reconstruir gerando um múnimo apenas de redo log, é o chamado modo
NOLOGGING, veja os detalhes na doc Oracle, em especial no manual "Oracle®
Database Administrator's Guide" no cap. 
16 Managing Indexes. Claro, é o ** TESTE ** no seu ambiente que vai indicar
se essa técnica é proveitosa ou não, muitas vezes é, mas cada caso é um
caso... E lógico :
- há RESTRIÇÕES para isso, como (entre outras) se o DML está ocorrendo
isoladamente, numa janela de manutenção, ou não
- há IMPLICAÇÕES na hora de se fazer recuperação dum objeto criado assim, o
DBA ** TEM ** que entendê-las Precisamente

Sobre o parelelismo, isso é um conceito bem comum no bd Oracle para bancos
não-oltp, consiste em (para operações LONGAS, que vão atuar em milhares de
blocos, o que parece ser o seu caso) pedir para o banco abrir várias
"threads", vários Processos simultâneos, cada um lendo um 'pedaço' da tabela
a trabalhar : via de regra, SE o hardware tem capacidade ociosa, é
MUITÍSSIMO mais eficiente se ter n processos no banco trabalhando juntos
cada um num pedaço do todo do que se ter apenas um, que enquanto está lendo
nâo atualiza e enquanto atualiza não está lendo... Vc indica isso na
cláusula PARALLEL da tabela/índice , ou pode utilizar o HINT de /*+ PARALLEL
no SQL : veja detalhes e referência na documentação Oracle, em especial no
manual de Concepts (isso é conceito básico) e no Administrator´s Guide
(vários capítulos falam sobre o assunto).

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...

[]s

Chiappa
--- Em oracle_br@yahoogrupos.com.br <mailto:oracle_br%40yahoogrupos.com.br>
, Samuel Corradi <corrad...@...> escreveu
>
> 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
<mailto:oracle_br%40yahoogrupos.com.br> , Samuel Corradi<corradibh@>
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
<mailto:oracle_br%40yahoogrupos.com.br> , Samuel Corradi<corradibh@>
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!
> >>>>
> >>>
> >>>
> >>>
> >>
> >
> >
> >
>





[As partes desta mensagem que não continham texto foram removidas]

Responder a