e-junior 0 Denunciar post Postado Junho 18, 2008 Olá pessoal tudo bom???? Bom tenho uma dúvida eu preciso atualizar um campo tabela x com referencia ao campo da tabela y. Meu problema é o seguinte está demorando muito pra finalizar a procedure. Eu estou pegando os resultados da tabela y e jogando para um cursor do tipo ROWTYPE e depois estou colocando o UPDATE dentro de um LOOP para atualizar a tabela x, não sei se essa e a melhor forma de fazer, as segestões q vcs tiverem eu agradeco. ##### INFO TABELAS ##### TABELA1 (17598 Linhas) Tabela2 (17045 Linhas) ##### PROCEDURE ##### create or replace PROCEDURE "TESTE" AS BEGIN DECLARE COUNTER NUMBER := 0; CURSOR c_sb IS SELECT B1_COD, B1_CUTMAN FROM TABELA1 WHERE B1_TIPO IN ('01','02','03','04'); atualiza c_sb%ROWTYPE; BEGIN OPEN c_sb; LOOP FETCH c_sb INTO atualiza; EXIT WHEN c_sb%NOTFOUND; COUNTER := COUNTER + 1; UPDATE TABELA2 TB2 SET TB2.B9_CUTMAN = atualiza.B1_CUTMAN WHERE TB2.B9_DATA = '20080131' AND TB2.B9_COD = atualiza.B1_COD; IF COUNTER > 1000 THEN COUNTER := 0; COMMIT; END IF; END LOOP; CLOSE c_sb; END; COMMIT; END TESTE; Compartilhar este post Link para o post Compartilhar em outros sites
Motta 645 Denunciar post Postado Junho 18, 2008 Até a 9i o Oracle não fazia update com base em 2 tabelas , logo a sua saíde de fazer via cursor está correta. A tabela2 tem índice , algum por data e cod ? Compartilhar este post Link para o post Compartilhar em outros sites
e-junior 0 Denunciar post Postado Junho 18, 2008 Então eu estou com o 9i aqui. Mas sobre os indices a tabela2 nao tem nenhum por data e cod no momente. Posso criar mas so tem um problema pq aqui temos o Microsiga e para incluir esses dois indices terei q incluir um terceiro q nao estou usando na procedure tipo "B9_FILIAL+B9_COD+B9_DATA" nesse caso nao utilizo esse campo "B9_FILIAL". Minha duvida e a seguinte criando o indice nesse critério vai ajudar???? Compartilhar este post Link para o post Compartilhar em outros sites
Motta 645 Denunciar post Postado Junho 18, 2008 Putz , nem reconheci a formação da Microsiga. Aqui a XX_FILIAL é ou ' ' ou '01' , já tentou colocar a b9_filial no WHERE do UPDATE , colocando na mesma ordem do índice Microsiga, deve melhorar. O índice existe no Oracle, não ? Compartilhar este post Link para o post Compartilhar em outros sites
NaPraia 12 Denunciar post Postado Junho 18, 2008 não entendi pq tens que inserir um 3º índice?? Coloca um índice na TB2.B9_COD e outro na atualiza.B1_COD; isso vai melhorar, ou usar FOR ALL no loop do cursor Compartilhar este post Link para o post Compartilhar em outros sites
e-junior 0 Denunciar post Postado Junho 18, 2008 Hehehehe, entao Microsiga em alguns pontos só atrapalha. Mas entao nao tem o indice para esses campos. Vou criar aqui. Na tabela1 q eu coloco os dados no cursor rowtype e bom colocar indice tambem ou pelo motivo deu estar usando rowtype atrapalha????? Obrigado!!! Compartilhar este post Link para o post Compartilhar em outros sites
e-junior 0 Denunciar post Postado Junho 18, 2008 não entendi pq tens que inserir um 3º índice?? Coloca um índice na TB2.B9_COD e outro na atualiza.B1_COD; isso vai melhorar, ou usar FOR ALL no loop do cursor Entao e o padrao do sistema aqui os indices tem q ser inseridos pelo configurador do mesmo. Compartilhar este post Link para o post Compartilhar em outros sites
Motta 645 Denunciar post Postado Junho 18, 2008 Já pensou em usar o recno ? Eu costumo fazer isto +ou- assim begin for r in (select tabela1.xx_campo , tabela2.r_e_c_n_o_ recno from tabela1,tabela2 where tabela1.xx_chave = tabela2.yy_chavefk and tabela1.xx_campo = ....) loop update tabela2 set yy_campo2 = r.xx_campo where r_e_c_n_o_ = r.recno; end loop; end; Com o recno acho que fica mais rápido. Compartilhar este post Link para o post Compartilhar em outros sites
e-junior 0 Denunciar post Postado Junho 19, 2008 Entao olhei aqui e com o recno não vai da pq a tabela2 e a tabela de saldos iniciais e o recno dela não é o mesmo q da tabela1 tipo ele nao e FK. Compartilhar este post Link para o post Compartilhar em outros sites
Motta 645 Denunciar post Postado Junho 19, 2008 Não a ideia é fazer um join de tabela1 e tabela2 e obter o recno da tabela2 , pois o recno é chave com certeza é muito mais rápida. Pelo que vi o join é B9_COD com B1_COD. Exemplo real Microsiga , ajustando nome da tabela de contas a receber com base na de clientes. BEGIN FOR R IN (SELECT A1_NREDUZ , SE1010.R_E_C_N_O_ RECNO FROM SA1010 , SE1010 WHERE A1_COD = E1_CLIENTE) LOOP UPDATE SE1010 SET E1_NOMCLI = R.A1_NREDUZ WHERE R_E_C_N_O_ = R.RECNO; END LOOP; Compartilhar este post Link para o post Compartilhar em outros sites
alphamek 2 Denunciar post Postado Junho 19, 2008 Bom.... acho que índices só vai piorar, pq vai aumentar o números de I/Os no seu banco de dados, pq será necessário DELETE/INSERT para seu UPDATE. 1-) Veja o plano de execução do SELECT do seu cursor. SELECT B1_COD, B1_CUTMAN FROM TABELA1 WHERE B1_TIPO IN ('01','02','03','04'); E poste para nós. 2-) Se possível, faça um trace de sessão (DBMS_SYSTEM.SET_SQL_TRACE_IN_SESSION) para identificar os passos que o Oracle Server está fazendo e se possui algum evento de wait associado. 3-) Tente utilizar um cursor Implícito usando Bulk Bind, e veja se melhora. 4-) Passe os parâmetros de STORAGE das tabelas A e B, para saber se não está com retenção de alocação nos EXTENTS, se consegue expandir ou problemas no FREELIST. 5-) Veja as estatísticas para as tabelas e índices utilizados. Tente postar essas primeiras dúvidas, que depois podemos prosseguir. Abraços, :blink: Compartilhar este post Link para o post Compartilhar em outros sites