Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

e-junior

Problema com atualização pesada em tabela

Recommended Posts

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

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

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

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

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

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

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

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

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

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

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

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.