Melhorar Performance
Galera eu estou fazendo um Procedure no Firebird 2.5 para Sugestão de Compra de Produtos, mas esta muito demorado (30seg), já criei os índices. Tem como melhorar essa performance?
CREATE OR ALTER PROCEDURE SP_PRODUTOS_MOV (
dt_ini date,
dt_fim date,
compra_para integer,
prazo_entrega integer,
perc_variacao numeric(5,2))
returns (
prod_id integer,
prod_ean varchar(14),
prod_descricao varchar(120),
prod_und_com varchar(6),
prod_valor_compra numeric(18,2),
prod_valor_venda numeric(18,2),
qtde_caixa numeric(5,2),
for_id integer,
for_nome_fantasia varchar(80),
qtde_entrada numeric(5,2),
mes_entrada varchar(200),
qtde_vendida numeric(5,2),
mes_venda varchar(200),
media_vendida numeric(5,2),
qtde_dias integer,
est_min numeric(5,2),
estoque numeric(5,2),
consumo_esperado numeric(5,2),
variacao_esperado numeric(5,2),
sugestao numeric(5,2),
sugestao_cxa numeric(5,2))
as
BEGIN
FOR
select
produtos.prod_id,
produtos.prod_ean,
produtos.prod_descricao,
produtos.prod_und_com,
coalesce(produtos.prod_valor_compra,0),
coalesce(produtos.prod_valor_venda,0),
coalesce(PRODUTOS.prod_estoq_min,0),
coalesce(produtos.qtde_caixa,0),
produtos.for_id,
fornecedor.for_nome_fantasia
from produtos
inner join fornecedor on (produtos.for_id = fornecedor.for_id)
order by produtos.for_id, produtos.prod_descricao
INTO :PROD_ID,
:PROD_EAN,
:PROD_DESCRICAO,
:PROD_UND_COM,
:PROD_VALOR_COMPRA,
:PROD_VALOR_VENDA,
:EST_MIN,
:qtde_caixa,
:FOR_ID,
:FOR_NOME_FANTASIA
DO
FOR
select
coalesce(sum(compras_itens.icp_qtde),0) as qtde
from compras_itens
inner join compras on (compras_itens.com_id = compras.com_id)
where
cast(compras.COM_DATA_COMPRA as date) between :dt_ini and :dt_fim and
compras_itens.prod_id = :prod_id
INTO:qtde_entrada
DO
FOR
select list('['|| iif(CHAR_LENGTH(COM_DATA_COMPRA) = 1, '0'|| COM_DATA_COMPRA,COM_DATA_COMPRA) || ' - Qt: ' || cast(qtde as integer)||']',' | ') from(
select
extract(month FROM compras.COM_DATA_COMPRA) as COM_DATA_COMPRA,
coalesce(sum(compras_itens.icp_qtde),0) as qtde
from compras_itens
inner join compras on (compras_itens.com_id = compras.com_id)
where
cast(compras.COM_DATA_COMPRA as date) between :dt_ini and :dt_fim and
compras_itens.prod_id = :prod_id
GROUP BY
extract(month FROM compras.COM_DATA_COMPRA) )
INTO:mes_entrada
DO
FOR
select
coalesce(sum(pedidos_itens.pi_qtde),0)
from pedidos
inner join pedidos_itens on (pedidos.ped_id = pedidos_itens.ped_id)
where
cast(pedidos.data_emissao as date) between :dt_ini and :dt_fim and
pedidos.status = 1 and
pedidos_itens.prod_id = :prod_id and
pedidos.tipo_id < 6
INTO :qtde_vendida
DO
FOR
select list('['|| iif(CHAR_LENGTH(data_emissao) = 1, '0'|| data_emissao,data_emissao) || ' - Qt: ' || cast(qtde as integer)||']',' | ') from(
select
extract(month FROM pedidos.data_emissao) as data_emissao,
coalesce(sum(pedidos_itens.pi_qtde),0) as qtde
from pedidos_itens
inner join pedidos on (pedidos_itens.ped_id = pedidos.ped_id)
where
cast(pedidos.data_emissao as date) between :dt_ini and :dt_fim and
pedidos.status = 1 and
pedidos_itens.prod_id = :prod_id and
pedidos.tipo_id < 6
GROUP BY
extract(month FROM pedidos.data_emissao) )
INTO:MES_VENDA
DO
FOR
select IIF(COALESCE(SUM(qtde),0) > 0, COALESCE(SUM(qtde),0) / COALESCE(COUNT(data_emissao),0),0) from(
select
extract(month FROM pedidos.data_emissao) as data_emissao,
coalesce(sum(pedidos_itens.pi_qtde),0) as qtde
from pedidos_itens
inner join pedidos on (pedidos_itens.ped_id = pedidos.ped_id)
where
cast(pedidos.data_emissao as date) between :dt_ini and :dt_fim and
pedidos.status = 1 and
pedidos_itens.prod_id = :prod_id and
pedidos.tipo_id < 6
GROUP BY
extract(month FROM pedidos.data_emissao) )
INTO :MEDIA_VENDIDA
DO
FOR
SELECT SUM(estoq_atual) FROM SP_GET_ESTOQUE_LOJAS(:prod_id)
INTO:ESTOQUE
DO
BEGIN
qtde_dias = datediff (day from :dt_ini to :dt_fim);
consumo_esperado = coalesce((MEDIA_VENDIDA / 30),0) * (coalesce(:compra_para,0) + coalesce(:prazo_entrega,0));
variacao_esperado = (consumo_esperado * coalesce(:perc_variacao,0)) / 100;
sugestao = (consumo_esperado + variacao_esperado + (est_min - estoque));
sugestao_cxa = sugestao * qtde_caixa;
SUSPEND;
END
END
Sidney Abreu
Curtidas 0
Respostas
Fabio Basso
26/08/2015
Olá Sidney,
Sua procedure está executando 7 selects. Quando você faz esses selects separadamente o retorno está sendo rápido (menos de 1 segundo)? Qual é a configuração do equipamento e qual é a quantidade de registros que estão sendo processados? Se você tiver uma base de dados de testes eu executaria isso em outro equipamento para compararmos o resultado.
Sua procedure está executando 7 selects. Quando você faz esses selects separadamente o retorno está sendo rápido (menos de 1 segundo)? Qual é a configuração do equipamento e qual é a quantidade de registros que estão sendo processados? Se você tiver uma base de dados de testes eu executaria isso em outro equipamento para compararmos o resultado.
GOSTEI 0
Sidney Abreu
26/08/2015
9 seg
GOSTEI 0