Autor Tópico: ** Resolvido ** Select com Inner Join muito demorado  (Lida 4277 vezes)

ZooSP

  • Novato
  • *
  • Mensagens: 37
    • Email
** Resolvido ** Select com Inner Join muito demorado
« Online: Abril 14, 2010, 04:46:15 pm »
Pessoal, tenho este select aqui na minha aplicação... Esta demorando um minuto e meio para trazer a resposta. Sei que quando fazemos Inner Joins com comparação de campos, ele verificar cada campo com todos da outra tabela. Acho que deve ser por isso a demora. Em média 1500 registros em cada tabela.


O que posso fazer para melhorar o desempenho? não entendo muito, mais penso que posso Indexar as tabelas... Mais nao sei fazer isso tbm...


alguem pode me ajudar por favor?

o código usado é este abaixo... Muito obrigado



SELECT
   comp.UnidComp_UnidadeCompetente,
   comp.UnidComp_IDRequisicao,
   comp.UnidComp_Status,
exec.Exec_IDExecucao,
   setex.DESCRICAO,
   exec.Exec_Executador,
   req.Rs_Unidade,
   req.Rs_TipoServico,
   req.Rs_Local,
   req.Rs_Prioridade,
   req.Rs_DataEmissao,
   req.Rs_Status,
   max(hist.Hist_Data) as dataultmov,
   DATEDIFF(CURDATE(),max(hist.Hist_Data)) as dias

FROM
   unidadecompetente comp
INNER JOIN requisicao req ON (comp.UnidComp_IDRequisicao = req.Rs_IDRequisicao)
INNER JOIN execucao exec ON (comp.UnidComp_IDUnidadeCompetente = exec.Exec_IDUnidadeCompetente)
INNER JOIN setorexecucao setex ON (exec.Exec_Setor = setex.IDSETEXECUCAO)
INNER JOIN historico hist ON (Hist_IDRequisicao = Rs_IDRequisicao)
WHERE
    comp.UnidComp_UnidadeCompetente like '[glo_unidade]' and Exec_Status = 1 and    comp.UnidComp_Status = 0
GROUP BY exec.Exec_IDExecucao
ORDER BY dataultmov DESC
« Última modificação: Abril 15, 2010, 04:23:07 pm por ZooSP »
Venha-nos Fazer uma Visita!!

robsonsilva

  • Visitante
Re: Select com Inner Join muito demorado
« Responder #1 Online: Abril 14, 2010, 05:58:42 pm »
Amigo,

Transforme estes campos da tua cláusula where em índices da tabela (Exec_Status e UnidComp_Status), e ordene as condições na tua query elegendo prioridades.

Para o banco, é mais rápido filtrar campos que são índices do que filtrar um varchar com condição "Like"... E a filtragem é executada na sequência informada na query, no teu caso por exemplo, primeiro ele estava pesquisando todos os registros com _UnidadeCompetente "parecido" com a global, e depois, nestes registros encontrados, procurando aqueles que correspondiam a cada status.

Portanto, você poderia inverter a sequência do teu where e colocar os campos "status" antes do campo texto:

WHERE
    Exec_Status = 1 AND
    comp.UnidComp_Status = 0 AND
    comp.UnidComp_UnidadeCompetente like '[glo_unidade]'


Não sei isso se me fiz entender e nem se isso vai resolver seu problema, mas talvez melhore um pouquinho..

Espero ter ajudado.

Att.
Robson

ZooSP

  • Novato
  • *
  • Mensagens: 37
    • Email
Re: Select com Inner Join muito demorado
« Responder #2 Online: Abril 15, 2010, 08:28:13 am »
Está praticamente instantâneo agora...


Nossa.. nem sei como te agradecer.. srsrsrsr



Veja meu ponto de vista... no caso a tabela "Comp" é a que tem menos registros ( 20 registros ) e a tabela "Exec" tem 3000 registros.  Coloraria a Exec antes, pois para cada registro = 1 na tabela exec, ele iria percorrer os 20 registros em Status=0.


é isso?
Venha-nos Fazer uma Visita!!

robsonsilva

  • Visitante
Re: Select com Inner Join muito demorado
« Responder #3 Online: Abril 15, 2010, 09:16:34 am »
Opa,

Que bom que funcionou... o negócio é criar índices e iniciar filtro com as condições que darão maior resultado (ou seja: retornarão menos registros para a próxima condição). 

A leitura no banco é feita registro a registro, filtrando os dados de acordo com as condições do where e enviando o resultado para a próximo condição, de acordo com a sequência informada no where.

Supondo que seu lookup tenha com 3 condições na clausula where e, rodando isoladamente cada condição do where (desconsiderando as outras), retornou o seguinte:

Condição A - retornou 6.000 registros
Condição B - retornou 3.000 registros
Condição C - retornou 1.000 registros

Ao unir as condições numa mesma query e nesta sequência (A and B and C), a condição B precisará "varrer" os 6.000 registros que retornaram da condição A, filtrando aqueles que também satisfaçam a condição B para que a condição C também possa "varrer".

O ideal neste caso seria colocar a condição C em 1ª lugar, pois restariam apenas 1.000 registros para as próximas condições verificarem. 

Outra coisa que é bom deixar pro final, por ser mais lento, é o operador Like. Principalmente se houverem "coringas" na expressão (% $).

Que confusa essa mensagem hehe.. se não me fiz entender é só avisar!

ZooSP

  • Novato
  • *
  • Mensagens: 37
    • Email
Re: Select com Inner Join muito demorado
« Responder #4 Online: Abril 15, 2010, 04:22:01 pm »
Oloco!! nem no google achei uma explicação dessa...rs rs

entendi perfeitamente... Muito obrigado mesmo pela aula.
Venha-nos Fazer uma Visita!!