[firebase-br] Aumentar a performance de uma consulta SQL
    Ana Virginia da Silva 
    virginia em farsoft.com.br
       
    Ter Maio 29 18:48:54 -03 2007
    
    
  
Pessoal, imagine a seguinte situação onde eu tenha 3 tabelas: 
PRODUTOS, PRECOS, ESTOQUE 
 
Eu preciso linkar as 3 juntas, ok? 
 
Só que eu preciso fazer isto mesmo que os produtos não tenham preço 
e nem estoque, ou seja, farei isto usando LEFT OUTER JOIN. 
 
Até aí tudo bem, agora imaginem que eu preciso pegar o preço da tabela
PRECOS, 
o estoque data tabela ESTOQUE sem que isto me gere repetições na tabela
PRODUTOS...Mas 
isto ocorreria pq tenho mais de uma tabela de preços e mais de uma qtde de
estoque, pois o 
estoque é por setor. 
 
usar group by eu não posso pq senão iria me gerar repetições...ja que teria
que incluir 
as colunas que mostro. 
 
Olhem o q montei inicialmente...não sei se tem como transformar alguns
blocos 
de codigo em views ou storeprocedures...gostaria da ajuda de algum de vcs
para 
melhorar isto...pq isto tá horrível: Tem mtos subselects...e pra dar
manutenção 
vcs já viram né... 
 
Pelo que sei no caso deste código abaixo, a query estará fazendo 
mtas consultas no banco, pois faço uma subselect pra 
cada coluna que preciso, como preco_custo, preco_venda, etc... 
 
Qualquer dica será bem vinda! 
 
select 
 
(select l.locacao from produtos_estoque pe, 
setores_estoque se, locacoes l 
where pe.is_produto=p.id_produto and se.id_setorestoque=pe.is_setorestoque 
and l.id_locacao=pe.is_locacao and (se.setor_estoque=:setorestoque2) 
and (pe.is_filial=:is_filial)) as locacao 
, 
 
(select sum(est.estoque) from produtos_estoque est where 
est.is_produto=p.id_produto and (est.is_filial=:is_filial2)) as
estoque_total 
, 
(select sum(pe.estoque) from produtos_estoque pe, 
setores_estoque se where pe.is_produto=p.id_produto 
and se.id_setorestoque=pe.is_setorestoque and (se
setor_estoque=:setorestoque) 
and (pe.is_filial=:is_filial3)) as estoque_setor, 
 
(select pr.preco_custo from precos pr, tabela_precos tp 
where tp.tabelapreco=:tabelapreco1 and pr.is_produto=p.id_produto 
and tp.id_tabelapreco=pr.is_tabelapreco 
order by pr.is_produto, tp.id_tabelapreco) as preco_custo 
, 
 
(select pr.preco_custoreal from precos pr, tabela_precos tp 
where tp.tabelapreco=:tabelapreco2 and pr.is_produto=p.id_produto 
and tp.id_tabelapreco=pr.is_tabelapreco order by pr.is_produto, tp
id_tabelapreco) as preco_custoreal 
, 
 
(select pr.preco_venda from precos pr, tabela_precos tp 
where tp.tabelapreco=:tabelapreco3 and pr.is_produto=p.id_produto 
and tp.id_tabelapreco=pr.is_tabelapreco order by pr.is_produto, tp
id_tabelapreco) as preco_venda 
, 
 
(select pr.preco_minimo from precos pr, tabela_precos tp 
where tp.tabelapreco=:tabelapreco4 and pr.is_produto=p.id_produto 
and tp.id_tabelapreco=pr.is_tabelapreco order by pr.is_produto, tp
id_tabelapreco) as preco_minimo 
, 
 
(select pr.desconto_maximo from precos pr, tabela_precos tp 
where tp.tabelapreco=:tabelapreco5 and pr.is_produto=p.id_produto 
and tp.id_tabelapreco=pr.is_tabelapreco order by pr.is_produto, tp
id_tabelapreco) as desconto_maximo 
, 
 
(select pr.desconto_revenda from precos pr, tabela_precos tp 
where tp.tabelapreco=:tabelapreco6 and pr.is_produto=p.id_produto 
and tp.id_tabelapreco=pr.is_tabelapreco order by pr.is_produto, tp
id_tabelapreco) as desconto_revenda 
, 
 
(select pr.promocao from precos pr, tabela_precos tp 
where tp.tabelapreco=:tabelapreco7 and pr.is_produto=p.id_produto 
and tp.id_tabelapreco=pr.is_tabelapreco order by pr.is_produto, tp
id_tabelapreco) as promocao 
, 
 
(select pr.preco_dolar from precos pr, tabela_precos tp 
where tp.tabelapreco=:tabelapreco8 and pr.is_produto=p.id_produto 
and tp.id_tabelapreco=pr.is_tabelapreco order by pr.is_produto, tp
id_tabelapreco) as preco_dolar 
, 
 
 
p.*, 
m.*, 
C.cor, 
GP.grupoproduto, 
PA.* 
 
from 
Produtos p 
LEFT OUTER JOIN 
MARCAS M 
on M.id_marca=p.is_marca 
LEFT OUTER JOIN 
CORES C 
on C.id_cor=p.is_cor 
LEFT OUTER JOIN 
grupos_produtos GP 
on GP.id_grupoproduto=p.is_grupoproduto 
LEFT OUTER JOIN 
PRINCIPIO_ATIVO PA 
on PA.id_principioativo=p.is_principioativo 
WHERE 1=1 
 
 
 
Segue abaixo o DDL das tabelas: 
 
CREATE TABLE PRECOS ( 
ID_PRECO INTEGER NOT NULL, 
IS_TABELAPRECO INTEGER NOT NULL, 
IS_PRODUTO INTEGER NOT NULL, 
PRECO_CUSTO NUMERIC(10,4), 
PRECO_CUSTOREAL NUMERIC(10,4), 
MARGEM_VENDA NUMERIC(6,2), 
PRECO_VENDA NUMERIC(10,4), 
PRECO_DOLAR VARCHAR(1), 
DESCONTO_MAXIMO NUMERIC(6,2), 
DESCONTO_REVENDA NUMERIC(6,2), 
MARGEM_MINIMA NUMERIC(6,2), 
PRECO_MINIMO NUMERIC(10,4), 
PROMOCAO VARCHAR(1), 
ULTIMA_ATUALIZACAO DATE 
); 
 
 
CREATE TABLE PRODUTOS ( 
ID_PRODUTO INTEGER NOT NULL, 
IS_GRUPOPRODUTO INTEGER, 
IS_MARCA INTEGER, 
IS_ST VARCHAR(3), 
IS_COR INTEGER, 
IS_PRINCIPIOATIVO INTEGER, 
IS_PRODUTOCATEGORIA INTEGER, 
ID_SIMILAR INTEGER, 
TIPO VARCHAR(1) NOT NULL, 
REFERENCIA VARCHAR(15), 
CODIGO_INTERNO VARCHAR(15), 
BARCODE VARCHAR(13), 
DESCRICAO VARCHAR(60) NOT NULL COLLATE PT_PT, 
DESCRICAO_RESUMIDA VARCHAR(25) COLLATE PT_PT, 
UN VARCHAR(3), 
EMBALAGEM NUMERIC(10,3), 
IPI NUMERIC(3,2), 
CST_A VARCHAR(1), 
CST_B VARCHAR(2), 
CF VARCHAR(8), 
APLICACAO BLOB SUB_TYPE 1 SEGMENT SIZE 8192, 
PESO NUMERIC(4,4), 
DATA_CADASTRO DATE NOT NULL, 
ATIVO VARCHAR(1), 
BRASINDICE_APRES VARCHAR(5), 
BRASINDICE_ITEM VARCHAR(5), 
BRASINDICE_LAB VARCHAR(5), 
DESCRICAOFONETICO VARCHAR(60) COLLATE PT_PT, 
PSICOTROPICO VARCHAR(1), 
PRONTO_SOCORRO VARCHAR(1), 
CODIGO_BRASINDICE VARCHAR(10) 
); 
 
CREATE TABLE PRODUTOS_ESTOQUE ( 
ID_PRODUTOESTOQUE INTEGER NOT NULL, 
IS_PRODUTO INTEGER NOT NULL, 
IS_SETORESTOQUE INTEGER NOT NULL, 
ESTOQUE NUMERIC(18,3) NOT NULL, 
ESTOQUE_MINIMO NUMERIC(18,3), 
ESTOQUE_MAXIMO NUMERIC(18,3), 
IS_LOCACAO INTEGER, 
IS_FILIAL INTEGER NOT NULL 
); 
 
 
    
    
Mais detalhes sobre a lista de discussão lista