Seguinte : sim, por DEFINIÇÃO quando vc cria um índice vc em muitos 
casos GANHA performance nas consultas, mas isso TEM A OUTRA FACE de 
implicar em diminuição de performance dos DMLs, já que a CADA DML 
feito o índice tem que ser atualizado (e índices são estruturas 
COMPLEXAS, que obrigatoriamente TEM QUE estarem fisicamente 
ordenados, é custoso atualizar índices) - isso está claramente 
exposto no manual "Oracle Concepts", que recomendo o estudo.
 Muito bem, continuando : no caso em questão vc está querendo 
introduzir um GRANDE volume de dados, PORTANTO isso é uma CARGA DE 
DADOS, uma rotina onde (claro) vc quer ter a maior performance 
possível em DMLs para que ela termine o quanto antes, pois NINGUÉM 
tem acesso aos dados antes deles carregarem... Em rotinas do tipo, 
SIM, é COMUM e RECOMENDADO vc desabilitar índices e constraints, 
justamente para EVITAR de "pagar o preço" do overhead a cada DML (ao 
final da rotina vc rebuilda os índices - em paralelo e nologging se 
possível -, desta menaira "pagando o preço" duma vez só, á vista tem 
desconto :_) , isso se deve PRINCIPALMENTE ao fato de que, SEM 
índices presentes, vc tem acesso ao modo NOLOGGING, que muitas vezes 
representa um ABSURDAMENTE ENORME ganho em performance, é técnica 
PADRÂO em bancos DW/batch, pesquise em http://asktom.oracle.com que 
vc acha diversos artigos e testes demonstrando isso.
 
==> Afora esse ponto, que vc DEVERÀ SIM implementar se minimamente 
possível, observo que  :

- a técnica de 

insert into tabela values ...
exception when dup_val_on_index
update tabela set 

==> é a PIOR DAS PIORES possíveis, pois vc FAZ o insert, gerando redo 
e undo, que se for duplicação VAI ser desfeito, gerando mais redo e 
tendo que ler o undo, ALTOS I/Os aí... Sem sombra de dúvida, se a sua 
versão de banco já tem e aceita, o comando SQL de MERGE seria ULTRA 
mais eficiente

- preferencialmente faz essa carga com uma ferramenta que gere SQL e 
envie diretamente esse SQL pro banco, em PL/SQL a cada SQL enviado 
pro banco vc PAGA UM PREÇO na forma de context switch, pra uns 
poucoas registros isso não é nada, MAS pra um grande volume 
rapidamente isso se torna HORRÍVEL, SQL direto é a melhor solução : 
se a carga é de um aqruivo-texto (tipicamente é) no banco 9i em 
diante vc tem INCLUSIVE a chance de usar o arquivo-texto como se 
fosse uma tabela, com a opção de EXTERNAL TABLE, aí o MERGE seria 
ainda mais eficiente...

e finalmente : SE realmente for (por qquer motivo) absolutamente, 
completamente, inequivocadamente impossível vc fazer em SQL apenas e 
tiver que usar PL/SQL, que AO MENOS vc use array processing e bulk 
collect, é isso.


[]s

 Chiappa
 
--- Em oracle_br@yahoogrupos.com.br, "rbr72" <[EMAIL PROTECTED]> escreveu
>
> Pessoal, tava analisando um problema num cliente, e percebi que o 
> processo mais demorado era um insert executado várias vezes numa 
> tabela. A lógica era mais ou menos essa abaixo, se já existia um 
> dado na tabela, era feito um update de valores.
> 
> insert into tabela values ...
> exception when dup_val_on_index
> update tabela set ...
> 
> No trace gerado pelo cliente, ele tentou executar 56000 inserts, 
> foram gravados somente 56 linhas, o resto foi tudo pro update. O 
> problema que pra executar os 56000 inserts demorou 300 segundos, os 
> updates foram bem rápidos.
> 
> Fazendo os testes, o problema era a primary key, eu desabilitei 
ela, 
> criei um indice normal, e fiz a verificacao se o registro existe, 
> faco update, senão, insert. Desse modo ficou bem rápido também.
> 
> O que eu gostaria de saber é a explicação pra isso, sei que, com a 
> primary key, é necessário atualizar o arquivo de indice a cada 
> insert. Mas no cliente só gravou 56 inserts, então conclui que o 
> problema em alguma verificação que a primary key força o oracle a 
> fazer. Alguém sabe o que o Oracle realiza nos inserts, e o porque 
da 
> demora? Outra coisa, tem como fazer o insert ficar mais rápido ou 
> uma solução melhor do que desabilitiar a pk? Se alguém tiver idéia 
> melhor ajuda, porque vou ter que alterar um monte de procedures. :-)
> 
> Obrigado
>


Responder a