- Este tópico contém 12 respostas, 5 vozes e foi atualizado pela última vez 16 anos, 3 meses atrás por
hudsona.
-
AutorPosts
-
22 de dezembro de 2009 às 11:54 pm #91723
hudsona
ParticipantePessoal To com o seguinte Update, que esta consumindo 100% de CPU:
DECLARE
intCont integer :=0;
BEGIN
FOR lcons IN (SELECT c.ident_contrato, c.cd_categoria FROM categoria_contrato c)
LOOP
BEGIN
UPDATE categoria_contrato SET CD_SUBCATEGORIA = lcons.cd_categoria WHERE ident_contrato = lcons.ident_contrato AND cd_categoria = lcons.cd_categoria;
END;
intCont := intCont+1;
END LOOP;
DBMS_OUTPUT.PUT_LINE(‘REGISTROS ATUALIZADOS ‘ || intcont);
END;Meu servidor é subdimensionado tem duas instancias mas
a que estou executando oupdate tem a seguinte configuração:
Intel Petium 4 2,80Ghz 2 Gb de RAMCom
920MB de SGA,
244MB de PGAAlguma sugestão ?
23 de dezembro de 2009 às 12:22 am #91725Regis Araujo
ParticipanteBoa tarde Hudson!
Só uma dúvida, pq vc está dando update dos dados da tabela categoria_contrato nela mesma?
Assim realmente irá consumir muita CPU, alem de gerar muito UNDO…
É algum teste?
Qual a quantidade de linhas que possui nesta tabela?
Abraços..
23 de dezembro de 2009 às 12:39 am #91728hudsona
ParticipanteA Tabela tem 263054;
E Ocupa Hoje 8388608 BYTESNa realidade poderia ter feito o seguinte comando:
UPDATE categoria_contrato SET CD_SUBCATEGORIA = cd_categoria ;
Sim é um testeE eu acho que não era pra consumir Tanto de CPU, pra mim tem alguma coisa a mais.
23 de dezembro de 2009 às 12:45 am #91729Regis Araujo
ParticipanteÉ..
Faz o seguinte.. coloca um COMMIT após o intCont := intCont+1;
Pois do jeito q está, ele gera muito SWAP e muito UNDO.. esta troca de SWAP que deve estar consumindo sua CPU…
(Bom, estou deduzindo q vc esteja usando Linux)…Este teste é para q?
Abraços..!
23 de dezembro de 2009 às 12:50 am #91730hudsona
ParticipanteE o pior que não
Estou Usando um Server 2003,Esse Teste é pra mostrar as merdas que eu seguro dos desenvolvedores,
Já tinha pensado no Commit também, mas como são muitas linhas,
acho melhor colocar um commit a cada um número determinado de linhas.
Se não quem vai começar a se ferrar é o buffer de redo log ….Na realidade eu não quero nem otpimizar isso, só quero mostrar as causas dele estar consumindo toda a minha CPU.
Obrigado !!
23 de dezembro de 2009 às 12:55 am #91734Regis Araujo
ParticipanteBom Hudson..!!
Então o jeito é gerar um TRACE desta sessão e analisar o resultado… ou um AWR ou ADDM…
Abraços..!!
23 de dezembro de 2009 às 12:59 am #91737hudsona
ParticipanteBoa!!
È Acho que vou gerar um AWR,
Obrigado!
23 de dezembro de 2009 às 2:01 am #91740burga
ParticipanteSerá que no seu update, ele não está reconhecendo as variáveis como bind? Vai saber… Dá pra testar definindo as binds explicitamente… rs!!!
23 de dezembro de 2009 às 5:42 am #91742fsitja
ParticipantePor que está fazendo num loop isso? O chaveamento de contexto das milhares de chamadas ao SQL engine desse loop está matando seu servidor. Faça tudo num update só, o desempenho vai melhorar muito.
Qual a PK da tabela? São as próprias colunas c.ident_contrato e c.cd_categoria? Se forem roda o seguinte:
BEGIN
UPDATE categoria_contrato SET cd_subcategoria = cd_categoria;
DBMS_OUTPUT.PUT_LINE('REGISTROS ATUALIZADOS ' || SQL%ROWCOUNT);
END;
Se mesmo assim for muito para a máquina, quebre em lotes por bulk collect, 100 a 100, por exemplo, para não detonar a PGA com uma estrutura muito pesada.
Sinceramente, 200 mil linhas não é muito. 2 milhões não é muito. Fala com o poderoso aí e baixa uma diretriz: “proibido usar CURSOR FOR LOOP na empresa”. 😆
Mas sem brincadeira agora, não se usa cursor for loop para qualquer coisa que necessite de um mínimo de escalabilidade ou desempenho. 😉
Dá uma olhada no link abaixo.
http://www.oracle.com/technology/oramag … sktom.html
Como diz o Tom Kyte sobre row-by-row (cursor for loops):
“the single most inefficient approach to loading data. I have a name for this type of approach: I call it SLOW by SLOW processing. Avoid it.”[]’s
Francisco23 de dezembro de 2009 às 3:43 pm #91748hudsona
Participante[quote=”hudsona”:pwx874q8]A Tabela tem 263054;
E Ocupa Hoje 8388608 BYTESNa realidade poderia ter feito o seguinte comando:
UPDATE categoria_contrato SET CD_SUBCATEGORIA = cd_categoria ;
Sim é um testeE eu acho que não era pra consumir Tanto de CPU, pra mim tem alguma coisa a mais.[/quote]
fsitja
Eu mesmo já sabia da solução do update, como disse nessa mensgaem acima, não fiz quem fez isso e faz diversas asneiras são so desenvolvedores aqui na empresa, só que essa foi o estopim pra mim.
Queria saber todos os problemas de performance que esse for loop pra um simples update poderia ter gerado.
Alguns eu já sabia e confirmei com os comentarios do Thunder_Catz,
E respondendo ao burga, sim ele reconhecia as variaveis como bind,
Ontém criei um snapshot com o awr e vou hoje mostrar o que aquele pequeno código fez com o servidor que é “uma maravilha”.
Mas Obrigado
E vou fazer uma reunião com o chefão pra bloquear o for loop, e depois vou ser linchado , já que 99% são desenvolvedores.
rs23 de dezembro de 2009 às 4:48 pm #91752Anônimo
Nossa, acompanhei linha a linha desse tópico, penso eu que devo passar pela mesma situação aqui na empresa. Tem os desenvolvedores que creio eu que devem fazer várias “&&#$#” no banco e como eu sou iniciante ainda na área não consigo enxergar e expor isso.
Mais logo logo chegará a minha a hora, a hora da vingança. Rsrs…
Se vc conseguir bloquear o for loop, boa sorte e se não conseguir boa sorte tb. Rsrsrs…
[]’s
Erik23 de dezembro de 2009 às 4:53 pm #91753fsitja
Participantehehe, foi mal da minha parte Hudsona, eu não reparei naquele pedaço do post, deve ser pq estava com sono já, quase 11 da noite. Eu tinha visto que você falou que foi outra pessoa, mas gastei o verbo de graça. 😀
Mas é isso aí, vc mandando o snapshot deve resolver a confusão, afinal contra fatos não há argumentos, vc até escapa com vida dessa sala cheia de desenvolvedores.
8)23 de dezembro de 2009 às 5:55 pm #91755hudsona
ParticipanteGastou o Verbo a Toa não fsitja
Vou usar seu comentario pra mostrar a ironia das pessoas ,
ao ver essas obras de arte ….rsrsrsrs
Sim, de qualquer forma já comprei um taco de basebool mesmo …
-
AutorPosts
- Você deve fazer login para responder a este tópico.