Performace de Select lento

Firebird

14/08/2012

Galera eu tenho um select que esta lento, ja criei indices e não consigo encontrar uma solução. por favor se alguem poder me ajudar eu agradeço.

eu uso o firebird 2.5, o resultado do select no ibexpert para 284 registros.

Plan
PLAN JOIN (JOIN (JOIN (USUARIOS NATURAL, PRODUTOS INDEX (FK_PRODUTOS_4), GRUPO_PROD INDEX (PK_GRUPO_PROD), FABRICANTE INDEX (PK_FABRICANTE), FORNECEDOR INDEX (RDB$PRIMARY2)), NCM_NEF NATURAL), CFOP NATURAL)

Adapted Plan
PLAN JOIN (JOIN (JOIN (USUARIOS NATURAL, PRODUTOS INDEX (FK_PRODUTOS_4), GRUPO_PROD INDEX (PK_GRUPO_PROD), FABRICANTE INDEX (PK_FABRICANTE), FORNECEDOR INDEX (INTEG_49)), NCM_NEF NATURAL), CFOP NATURAL)

------ Performance info ------
Prepare time = 15ms
Execute time = 437ms
Avg fetch time = 29,13 ms
Current memory = 10.207.916
Max memory = 14.099.452
Memory buffers = 2.048
Reads from disk to cache = 0
Writes from cache to disk = 0
Fetches from cache = 3.886.096


O select é o seguinte:

select
produtos.prod_id,
produtos.prod_codigo,
produtos.prod_descricao,
produtos.prod_descricao_fiscal,
produtos.prod_palavra_chave,
produtos.prod_ean,
produtos.prod_ncm,
ncm_nef.descricao as ncm_descricao,
produtos.prod_cfop,
cfop.descricao as cfop_descricao,
produtos.prod_ex_tipi,
produtos.prod_genero,
produtos.prod_und_com,
produtos.prod_valor_unit_com,
produtos.prod_und_trib,
produtos.prod_valor_unit_trib,
produtos.prod_ean_trib,
produtos.prod_tipo_tributacao,
produtos.prod_valor_compra,
produtos.prod_comissao,
produtos.prod_margem_lucro,
produtos.prod_valor_atacado,
produtos.prod_valor_varejo,
produtos.prod_valor_venda,
produtos.prod_valor_promocao,
produtos.prod_estoq_min,
produtos.prod_estoq_max,
produtos.prod_estoq_ideal,
produtos.qtde_caixa,
produtos.prod_peso,
produtos.prod_tamanho,
produtos.prod_cor,
produtos.for_id,
produtos.fab_id,
produtos.gru_id,
produtos.usu_id,
produtos.data_cad,
produtos.data_alt,
case
when produtos.status = A then ATIVO
when produtos.status = I then INATIVO
end status,
produtos.mobile,
fabricante.fab_nome,
fornecedor.for_nome,
grupo_prod.grupo,
usuarios.usu_login
from produtos
inner join usuarios on (produtos.usu_id = usuarios.usu_id)
inner join grupo_prod on (produtos.gru_id = grupo_prod.gru_id)
inner join fabricante on (produtos.fab_id = fabricante.fab_id)
inner join fornecedor on (produtos.for_id = fornecedor.for_id)
left join ncm_nef on (produtos.prod_ncm = ncm_nef.codigo)
left join cfop on (produtos.prod_cfop = cfop.cfop)


os indeces são: CREATE INDEX PRODUTOS_IDX1 ON PRODUTOS (PROD_DESCRICAO, PROD_ID)
Sidney Abreu

Sidney Abreu

Curtidas 0

Respostas

Eduardo Gonçalves

Eduardo Gonçalves

14/08/2012


select
...
from produtos
inner join usuarios on (produtos.usu_id = usuarios.usu_id)
inner join grupo_prod on (produtos.gru_id = grupo_prod.gru_id)
inner join fabricante on (produtos.fab_id = fabricante.fab_id)
inner join fornecedor on (produtos.for_id = fornecedor.for_id)
left join ncm_nef on (produtos.prod_ncm = ncm_nef.codigo)
left join cfop on (produtos.prod_cfop = cfop.cfop)


os indices são: CREATE INDEX PRODUTOS_IDX1 ON PRODUTOS (PROD_DESCRICAO, PROD_ID)


O índice por descrição e id do produto não influencia em nada nessa consulta, pois os campos PROD_ID e PROD_DESCRICAO não estão envolvidos no inner_join e nem em qualquer cláusula where. O que você pode fazer para tentar melhorar é criar índices em cima dos campos estão no inner join. Vai criando aos poucos, testando aos poucos e veja se a consulta melhora. Por exemplo, você pode começar criando um índice para produtos.fab_id, criar para produtos.prod_ncm e por aí vai. É importante também que os campos ncm_nef.codigo, fabricante.fab_id, fornecedor.for_id, usuarios.usu_id, grupo_prod.gru_id, cfop.cfop sejam todos chave primária em suas tabelas, pois assim são indexados automaticamente. Se você tiver esquecido de colocar um desses caras como chave primária, já pode ser o motivo da performance baixa na consulta.

GOSTEI 0
Bruno Leandro

Bruno Leandro

14/08/2012

soh apareceu um indice na tabela de produtos mas acredito que o ideial seria ter indices nos campos amarrados, caso tenha outros indices postar os mesmos para ver a melhor solução

inner join usuarios on (produtos.usu_id = usuarios.usu_id)
inner join grupo_prod on (produtos.gru_id = grupo_prod.gru_id)
inner join fabricante on (produtos.fab_id = fabricante.fab_id)
inner join fornecedor on (produtos.for_id = fornecedor.for_id)
left join ncm_nef on (produtos.prod_ncm = ncm_nef.codigo)
left join cfop on (produtos.prod_cfop = cfop.cfop)
GOSTEI 0
Deivison Melo

Deivison Melo

14/08/2012

Siga as orientações dos colaboradores acima, caso o problema não seja solucionado, por favor, postar novamente para que com isso acharmos a melhor solução que possa atendê-lo.
GOSTEI 0
Sidney Abreu

Sidney Abreu

14/08/2012

Galera valeu pela dica, criei os índices e melhorou consideravelmente. obrigado a todos.
GOSTEI 0
Sidney Abreu

Sidney Abreu

14/08/2012

Galera eu estou com um grande problema agora em um select, uns dos mais importantes, o de Clientes. Vou tentar explicar as regras de negocio para melhor compreenção de todos;

Cada cliente ele pertence a uma rota x, e cada rota x pertencence a um setor x, mas cada setor tem um conjunto de rotas, e cada setor x pertence a uma area.

Então eu fiz assim:


Link do DER ... [url]http://www.7master.com.br/DER.gif[/url]




e o meu select eu fiz assim:

select distinct
clientes.cli_id,
clientes.cli_nome,
clientes.cli_endereco,
clientes.cli_numero,
clientes.cli_bairro,
clientes.cli_cidade,
clientes.cli_cep,
clientes.cli_uf,
clientes.cli_ibge,
clientes.cli_fone1,
clientes.cli_fone2,
clientes.cli_fone3,
clientes.cli_fax,
clientes.cli_rg,
clientes.cli_cpf_cnpj,
clientes.cli_mail,
clientes.cli_site,
clientes.cli_limite,
clientes.cli_saldo,
clientes.cli_tipo,
clientes.cli_tabela,
case clientes.status
when 0 then ATIVO
when 1 then INATIVO
when 2 then BLOQUEADO
end as STATUS,
clientes.cli_foto,
clientes.cli_obs,
clientes.data_cad,
clientes.data_alt,
clientes.cli_nascimento,
clientes.cli_creditoconsumo,
clientes.cli_creditotipo,
clientes.cli_razao,
clientes.cli_validadecartao,
clientes.cli_complemento,
clientes.cli_contato,
clientes.cli_categoria,
clientes.cli_classe,
clientes.cli_login,
clientes.cli_senha,
clientes.cli_vendas,
clientes.cli_suframa,
clientes.usu_id,
usuarios.usu_login,
clientes.loj_id,
clientes.data_bloqueio,
clientes.motivo_bloqueio,
clientes.data_desbloqueio,
clientes.motivo_desbloqueio,
clientes.rot_id,
rotas.rot_descricao,
areas.are_descricao,
clientes.cli_intinerario,
clientes.isento_icms,
clientes.sintegra_situacao,
clientes.sintegra_data_consulta,
setores.set_descricao,
clientes.imprimir,
clientes.ASSINATURA_PDA
from clientes
inner join setores
on (setores.rota1 = clientes.rot_id)
or (setores.rota2 = clientes.rot_id)
or (setores.rota3 = clientes.rot_id)
or (setores.rota4 = clientes.rot_id)
or (setores.rota5 = clientes.rot_id)
or (setores.rota6 = clientes.rot_id)
or (setores.rota7 = clientes.rot_id)
left join rotas on rotas.rot_id = clientes.rot_id
inner join areas on areas.are_id = setores.are_id
left join usuarios on usuarios.usu_id = clientes.usu_id
order by clientes.cli_id


mas esta muito lento, alguem tem alguma idéia de como posso melhorar?
GOSTEI 0
POSTAR