** Resolvido ** Select com Inner Join muito demorado

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

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:

[tt]WHERE
Exec_Status = 1 AND
comp.UnidComp_Status = 0 AND
comp.UnidComp_UnidadeCompetente like ‘[glo_unidade]’[/tt]

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

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?

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!

Oloco!! nem no google achei uma explicação dessa…rs rs

entendi perfeitamente… Muito obrigado mesmo pela aula.