Melhorar o desempenho de um select com Inner Join
22/08/2007
0
Tenho duas tabelas distintas no Mysql com mais de 900.000 registros, onde faço o seguinte comando:
Select * from tdcupant INNER JOIN finafim ON (tdcupant.numcupom = finafim.numcup and tdcupant.impcaixa = finafim.impcaixa and tdcupant.dtcompra = finafim.dtcomp) where dtcompra >=:inicio and dtcompra <=:fim order by dtcompra, hora
É meio brabo, mas acreditem, é necessário. :(
Quando efetuo uma busca, digamos do dia 01/05/07 a 20/06/07, o sistema demora cerca de 15 min, sem falar que gera uma inconsistência no servidor, deixando os outros PC´s lentos. Gostaria de saber se existe alguma forma de melhorar o desempenho dessa consulta.
Grato pela atenção.
Obs: Utilizo delphi 7 com o Zeos e Mysql 4.0.22
Turbo Drive
Posts
22/08/2007
Emerson Nascimento
22/08/2007
Adriano Santos
TDCUPANT = 900.000 registros
FINAFIM = 300.000 registros
OUTRA_TABELA = 1.000 registros
O seu join deverá começar pelas tabelas menores, ou seja, por OUTRA_TABELA, depois FINAFIM e por ultimo TDCUPANT. Por que isso?
Bem, quando o banco chegar na última tabela do join, grande parte dos registros já estarão separados, filtrados levando menos tempo dentro da tabela com 900.000 registros.
Claro que no seu caso não ajuda muito, mas deve melhorar um pouco a performance.
Mas não esqueça o que o emerson.en dissse. Crie indices, não dá pra fazer mágina com esse volume de dados.
Abs
23/08/2007
Turbo Drive
23/08/2007
Adriano Santos
[b:b2b8d0c71d]Turbo Drive[/b:b2b8d0c71d] os índices são, grosseiramente falando, como o índice de um livro. É por ele que o banco de dados se orienta pra encontrar mais rapidamente os registros. Todo banco de dados tem este recurso.
Para se criar índice no Firebird por exemplo faça desta forma:
CREATE UNIQUE INDEX NOME_DO_INDEX ON FORNECEDORES (CNPJ,FANTASIA,RAZAO)
Aqui, estou criando um índice único com o nome [b:b2b8d0c71d]NOME_DO_INDEX[/b:b2b8d0c71d], na tabela [b:b2b8d0c71d]FORNECEDORES [/b:b2b8d0c71d]com os campoas [b:b2b8d0c71d]CNPJ, FANTASIA e RAZAO[/b:b2b8d0c71d]. Por ser único ([b:b2b8d0c71d]UNIQUE[/b:b2b8d0c71d]) não poderei incluir um fornecedore com o mesmo [b:b2b8d0c71d]CNPJ, FANTASIA e RAZAO[/b:b2b8d0c71d] que já exista na base de dados.
Você pode criar quantos índices forem necessários para o seu banco de dados. Mas índice não é só pra esta utilidade. Os índices ajudam a integridade de dados como Checks, Constraints e Foreign Keys. Ajudam na ordenação e etc.
Qualquer dúvida entre novamente em contato.
14/09/2007
Rodrigobertero
Não utilize *, informe os campos que deseja carregar
Utilize o between no lugar do >= e <=
Conforme abaixo:
Select campo1, campo2, campo3 from tdcupant
INNER JOIN finafim ON
(tdcupant.numcupom = finafim.numcup and
tdcupant.impcaixa = finafim.impcaixa and
tdcupant.dtcompra = finafim.dtcomp)
where dtcompra between :inicio and :fim
order by dtcompra, hora
Clique aqui para fazer login e interagir na Comunidade :)