[firebase-br] Consulta Muito, Muito Lenta

eduardo eduardo em icontroller.com.br
Sex Jul 29 17:35:50 -03 2005


Olá Valdir Dill

> SELECT P.CODIGO, P.DESCRICAO, P.UNIDADE, P.MARCA, P.ESTOQUEMINIMO,
>  P.ATUAL,
> CASE ME.OPERACAO WHEN 'E' THEN SUM(ME.QUANTIDADE) END AS ENTRADAS,
> CASE ME.OPERACAO WHEN 'S' THEN SUM(ME.QUANTIDADE) END AS SAIDAS
Acho que estes CASEs, considerando que são agregados estão dificultando 
as coisas pro banco.
Experimente assim:

SUM(CASE WHEN ME.OPERACAO='E' THEN ME.QUANTIDADE ELSE 0 END) AS ENTRADAS,
SUM(CASE WHEN ME.OPERACAO='S' THEN ME.QUANTIDADE ELSE 0 END) AS SAIDAS,

> FROM PRODUTOS P
> LEFT JOIN MOVIESTOQUE ME ON (ME.PRODUTO = P.CODIGO 

> AND ME.DATA >:VDataPosicao)

Os JOINS devem, preferencialmente ter uma relação de 1 para 1. Esta 
parte iria melhor no WHERE
WHERE ME.DATA >:VDataPosicao)

> GROUP BY
> P.CODIGO, P.DESCRICAO, P.UNIDADE, P.MARCA, P.ESTOQUEMINIMO, P.ATUAL,
>  ME.OPERACAO

Algumas vezes, subselects trazem vantagens sobre o Agrupamento, 
principalmente no seu caso onde a quantidade de datas armazenadas pode 
ser bem maior dos que a do período que você quer.

Você poderia tentar algo como:

SELECT DISTINCT
    P.CODIGO, P.DESCRICAO, P.UNIDADE, P.MARCA, P.ESTOQUEMINIMO, P.ATUAL,
    SELECT(
            SUM(QUANTIDADE)
            FROM MOVIESTOQUE
            WHERE PRODUTO = P.CODIGO
                  AND DATA>:VDataPosicao
                  AND OPERACAO='E'
          )  AS ENTRADAS,
    SELECT(
            SUM(QUANTIDADE)
            FROM MOVIESTOQUE
            WHERE PRODUTO = P.CODIGO
                  AND DATA>:VDataPosicao
                  AND OPERACAO='S'
          )  AS SAIDAS
FROM PRODUTOS P

Um índice em PRODUTO, DATA na tabela MOVIESTOQUE vai otimizar o 
resultado em ambos os casos

> Se o cadastro de produtos tiver mais que 2500 itens, chega a demorar
>  mais de 5 minutos para abrir. Por que será tanta demora? Alguém teria
>  alguma sugestão para fazer essa consulta de forma diferente e que fosse
>  mais rápida?
> 
> Utilizo Firebird 1.5

Você precisa acesso bidirecional?
Componentes unidirecionais são mais rápidos para grandes volumes, pois 
dão fetch sob demanda. Se precisar ser bidirecional, ainda assim você 
pode usar a propriedade PackedRecords e trazer em "Blocos" de 20 ou 30 
registros, o que também melhora a performance inicial.

Espero ter ajudado

Forte Abraço, Eduardo





Mais detalhes sobre a lista de discussão lista