Olá Marcelo, > Ou será que é melhor fazer pela aplicação?
Nem a pau! Servidor não se chama servidor para mandar estação fazer conta. Uma forma simples de aumentar consideravelmente o desempenho é trocando LEFT por INNER, mesmo que com isso teu SQL fique bem grande. Isso te poupará desses incômodos COALESCE e dos abomináveis OR na cláusula WHERE, além de permitir o uso de diversos índices simultaneamente, o que deve melhorar bastante o desempenho. Sugiro algo como isso aqui: select x.cod_id, x.nome, x.codigo, sum(x.qtd_itens) as qtd_itens, sum(x.qtd_balcao) as qtd_balcao, sum(x.qtd_baixa) as qtd_baixa, sum(x.qtd_venda) as qtd_venda from ( select a.cod_id, a.nome, b.codigo, sum(c.qtd_item) as qtd_itens, 0 as qtd_balcao, 0 as qtd_baixa, 0 as qtd_venda from mv_clientes a inner join mv_vendas_pre_itens c on(c.cod_id = a.cod_id) and (c.codigo <> '00') group by a.cod_id, a.nome, b.codigo UNION ALL select a.cod_id, a.nome, d.codigo, 0 as qtd_itens, sum(d.qtd_item) as qtd_balcao, 0 as qtd_baixa, 0 as qtd_venda from mv_clientes a inner join mv_servicos_balcao d on(d.cod_id = a.cod_id) and (d.codigo <> '00') group by a.cod_id, a.nome, b.codigo UNION ALL select a.cod_id, a.nome, e.codigo, 0 as qtd_itens, 0 as qtd_balcao, sum(e.qtd_item) as qtd_baixa, 0 as qtd_venda from mv_clientes a inner join mv_servicos_baixa e on(e.cod_id = a.cod_id) and (e.codigo <> '00') group by a.cod_id, a.nome, e.codigo UNION ALL select a.cod_id, a.nome, f.codigo 0 as qtd_itens, 0 as qtd_balcao, 0 as qtd_baixa, sum(f.qtd_item) as qtd_venda from mv_clientes a inner join mv_vendas_itens f on(f.cod_id = a.cod_id) and (f.codigo <> '00') group by a.cod_id, a.nome, f.codigo ) as x inner join mv_produtos b on (x.codigo = b.codigo) group by x.cod_id, x.nome, x.codigo, b.descricao order by 1,2,3,4 Analise o plano de execução para ver se o INNER com os produtos não ficaria melhor dentro do subselect. Isso teoricamente pode ser vantajoso dependendo da quatidade de produtos diferentes do seu cadastro e da quantidade de clientes diferentes do seu cadastro. Daria também para testar fazer o join com a mv_clientes fora da totalização inicial, como eu fiz com os produtos. Só testando para ver se fica só melhor ou se fica inacreditavelmente rápido. Índices com produto, cliente e o qtd_item nas 4 tabelas totalizadas também poderia ajudar bastante, experimente criá-los para tentar melhorar o desempenho ainda mais. Novamente será a proporção clientes x produtos que determinará se é melhor fazer "cliente, produto, qtd_item" ou "produto, cliente, qtd_item". Crie os dois e veja pelo plano de execução qual o elefantinho mais gostou. De qualquer forma, o princípio da otimização permanece: não há mais LEFT JOINs (que o elefantinho sofre para resolver), não há mais COALESCEs (que atrapalham a vida do elefantinho) e não há mais ORs/IS NULLs (desgraça para qualquer servidor SQL). Atenciosamente, Mozart Hasse _______________________________________________ pgbr-geral mailing list [email protected] https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral
