Pessoal ,

 

que acham da gente mudar o pensamento.

 

Tive um caso esses dias bem interessante .

 

Uma certa empresa tinha um processo que executava todo dia, e demorava entre 40 a 50 minutos.

 

Quando abri a proc estava assim :

 

declare @codigo int

declare @valor float

 

declare ccursor cursor for

select codigo,

         valor

from tab1

 

open ccursor

 

fetch next from ccursor into @codigo,@valor

 

WHILE @@FETCH_STATUS = 0

BEGIN

 if exists (select 1 from tab2 where codigo = @codigo)

  update tab2 set valortab2 = valortab1 + @valor where codigo = @codigo

 else

  insert into tab2(codigo, valortab1,valortab2) values (@codigo,@valor,0)

 

 fetch next from ccursor into @codigo,@valor

 

end

 

close ccursor

deallocate ccursor 

 

 

 

Ou seja, para cada linha de tab1 procurava-se em TAB2. Se existisse atualizava o valor, se não inseria uma nova linha.

 

Este processo assim, para 980 mil linhas na TAB1, demorava 47 minutos.

 

Bom, este é o tipico pensamento llinha a linha, que a maiora de desenvolvedore seniors tem (inclsuive eu tive) pois viemos de uma epoca ( era micro) que os recursos eram limitados (ou não eram difundidos) neste aspecto.

 

Eu mesmo fui programador clipper muitos anos, era seek e do while.

 

Mas e se a gente mudasse o pensamento ?

 

E se a gente atualizasse o que existe e inserisse o que não existe ?...

 

Vamos mais a fundo e se a gente atualizasse o que existe, guardasse o codigo destas linhas atualizadas numa tabela e inserisse na tab2 as que nao existem no join da tab1 com esta nova tabela.

 

Vamos lá

 

declare @tabela table (codigo int)

 

update  a

set        a.valortab2 = a.valortab1 + b.valor

OUTPUT inserted.codigo INTO @tabela

from tab2 a,

        tab1 b

where a.codigo = b.codigo

 

insert into tab2( codigo,

                        valortab1,

                        valortab2

                      )

select a.codigo,

         a.valor,

         0

from  tab1 a

where not exists ( select 1

                           from @tabela b

                           where a.codigo = b.codigo

                         )

 

Esta alteração de pensamento, passou para 7 segundos, de 5 a 7 em média.

 

Usando a clausula output (pois era 2005..se fosse 2008 eu usaria o merge) eu coloquei na @tabelas as linhas que foram atualizadas e depois inseri as que nao tivessem no join dela com a tab1

 

O que eu fiz ?..

Nada de milagres ou tecnicas extraordinárias de tuning,simplesmente pensei SET BASED

 

[b]Conjunto de linhas e nao linha a linha. [/b]

 

Grande abraço a todos

 

$hell your experience !!!

www.laertejuniordba.spaces.live.com