Pular para o conteúdo
Visualizando 13 posts - 1 até 13 (de 13 do total)
  • Autor
    Posts
  • #91723
    hudsona
    Participante

      Pessoal 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 RAM

      Com
      920MB de SGA,
      244MB de PGA

      Alguma sugestão ?

      #91725
      Avatar photoRegis Araujo
      Participante

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

        #91728
        hudsona
        Participante

          A Tabela tem 263054;
          E Ocupa Hoje 8388608 BYTES

          Na realidade poderia ter feito o seguinte comando:

          UPDATE categoria_contrato SET CD_SUBCATEGORIA = cd_categoria ;
          Sim é um teste

          E eu acho que não era pra consumir Tanto de CPU, pra mim tem alguma coisa a mais.

          #91729
          Avatar photoRegis 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..!

            #91730
            hudsona
            Participante

              E 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 !!

              #91734
              Avatar photoRegis Araujo
              Participante

                Bom Hudson..!!

                Então o jeito é gerar um TRACE desta sessão e analisar o resultado… ou um AWR ou ADDM…

                Abraços..!!

                #91737
                hudsona
                Participante

                  Boa!!

                  È Acho que vou gerar um AWR,

                  Obrigado!

                  #91740
                  burga
                  Participante

                    Será que no seu update, ele não está reconhecendo as variáveis como bind? Vai saber… Dá pra testar definindo as binds explicitamente… rs!!!

                    #91742
                    fsitja
                    Participante

                      Por 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
                      Francisco

                      #91748
                      hudsona
                      Participante

                        [quote=”hudsona”:pwx874q8]A Tabela tem 263054;
                        E Ocupa Hoje 8388608 BYTES

                        Na realidade poderia ter feito o seguinte comando:

                        UPDATE categoria_contrato SET CD_SUBCATEGORIA = cd_categoria ;
                        Sim é um teste

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

                        #91752
                        Anô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
                          Erik

                          #91753
                          fsitja
                          Participante

                            hehe, 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)

                            #91755
                            hudsona
                            Participante

                              Gastou 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 …

                            Visualizando 13 posts - 1 até 13 (de 13 do total)
                            • Você deve fazer login para responder a este tópico.