Melhorar o desempenho de um select com Inner Join

MySQL

22/08/2007

Boa tarde a todos.

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

Turbo Drive

Curtidas 0

Respostas

Emerson Nascimento

Emerson Nascimento

22/08/2007

crie índices para os campos envolvidos no relacionamento, no [i:19c2cdec39]where[/i:19c2cdec39] e no [i:19c2cdec39]order by[/i:19c2cdec39].


GOSTEI 0
Adriano Santos

Adriano Santos

22/08/2007

Cara você pode levar em consideração no seu JOIN também o tamanho de registros de cada tabela e fazer o Join de acordo com isso, por exemplo:

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


GOSTEI 0
Turbo Drive

Turbo Drive

22/08/2007

Beleza galera. Desculpe a ignorância, mas o q seriam esses índices e como utilizá-los ?


GOSTEI 0
Adriano Santos

Adriano Santos

22/08/2007

[quote:b2b8d0c71d=´Turbo Drive´]Beleza galera. Desculpe a ignorância, mas o q seriam esses índices e como utilizá-los ?[/quote:b2b8d0c71d]
[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.


GOSTEI 0
Rodrigobertero

Rodrigobertero

22/08/2007

Importante a criação de Indice para performance da consulta SQL
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


GOSTEI 0
POSTAR