Re: [pgbr-geral] Otimizar consulta com LEFT JOIN

2010-06-22 Por tôpico Eduardo Amaral
Amanha mesmo, estarei testando... muito obrigado Mozart

Em 21 de junho de 2010 22:52, Mozart Hasse mozart.ha...@usa.net escreveu:

 Olá Eduardo,

  Depois de ler a técnica tentei de todo jeito mas não fui muito feliz...

  Vamos mudar o placar então.
  Não conheço a regra de negócio dessas tabelas, mas pelo que entendi são
 duas
  subconsultas independentes, sendo assim, vejamos:
  * o segundo UNION não pode ter os INNER que você colocou no primeiro,
 basta
  ter o NOT EXISTS.
  * são DOIS outer joins, logo você pode precisar de até 4 subconsultas (3
  unions)
  Então sua consulta ficará:
  1. Consulta original trocando OUTER por INNER
  2. Consulta original trocando OUTER por INNER no primeiro LEFT e trocando
 o
  segundo LEFT por um WHERE NOT EXISTS
  3. Consulta original trocando OUTER por INNER no segundo LEFT e trocando o
  primeiro LEFT por um WHERE NOT EXISTS
  4. Consulta original sem OUTER nem INNER, e na cláusula WHERE você coloca
 um
  NOT EXISTS para o primeiro LEFT e outro NOT EXISTS para o segundo

 Mozart Hasse
 (desculpem o vacilo no botão enviar da mensagem anterior)

 ___
 pgbr-geral mailing list
 pgbr-geral@listas.postgresql.org.br
 https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral




-- 
Att.,

Eduardo Amaral
___
pgbr-geral mailing list
pgbr-geral@listas.postgresql.org.br
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral


Re: [pgbr-geral] Otimizar consulta com LEFT JOIN

2010-06-21 Por tôpico Eduardo Amaral
Mozar,

Depois de ler a técnica tentei de todo jeito mas não fui muito feliz...

A 1 Parte com Inner, ficou muito RAPIDO
Acho que fiz errado , na segunda parte pq piorou o tempo da query
anterior

essa é a query

(ja tomei de uns 8x0 dela)




---


SELECT

 a.sg_uf,c.co_tp_complemento
,DECODE(c.co_tp_complemento,'1','L','2','M','3','C')ds_tp_complemento
,SUM(NVL(a.qt_saldo_ano_anterior,0))qt_saldo_ano_anterior
,SUM(NVL(a.qt_recebido,0))qt_recebido
,SUM(NVL(remRec.qt_rem_recebido,0))qt_rem_recebido
,SUM(NVL(remEfe.qt_rem_efetuado,0))qt_rem_efetuado
,SUM(NVL(a.qt_saldo_ano_anterior,0) +
(NVL(a.qt_recebido,0)+NVL(remRec.qt_rem_recebido,0)+NVL(remEfe.qt_rem_efetuado,0)))
qt_total_livros

FROM simad.i_livro_pnl c  , simad.i_livro_distribuido_pnl a

LEFT OUTER JOIN

(SELECT
r.an_programa,r.nu_seq_livro,r.nu_seq_destino,r.nu_seq_prog_acao_distr,
  sum(r.qt_remanejamento_recebido) qt_rem_recebido

 FROM simad.i_remanejamento_pnl r
 WHERE r.nu_seq_destino  0
   AND r.an_programa = '2010'
   AND r.nu_seq_prog_acao_distr = 1

GROUP BY r.an_programa, r.nu_seq_livro, r.nu_seq_destino,
r.nu_seq_prog_acao_distr)remRec

ON  remRec.nu_seq_livro = a.nu_seq_livro AND remRec.nu_seq_destino =
a.nu_seq_entidade


LEFT OUTER JOIN

(SELECT
r.an_programa,r.nu_seq_livro,r.nu_seq_origem,r.nu_seq_prog_acao_distr,
  sum(r.qt_remanejamento_efetuado) qt_rem_efetuado

 FROM simad.i_remanejamento_pnl r

 WHERE r.nu_seq_origem  0
   AND r.an_programa = '2010'
   AND r.nu_seq_prog_acao_distr = 1

 GROUP BY r.an_programa, r.nu_seq_livro, r.nu_seq_origem,
r.nu_seq_prog_acao_distr)remEfe

ON  remEfe.nu_seq_livro = a.nu_seq_livro

AND remEfe.nu_seq_origem = a.nu_seq_entidade

WHERE a.nu_seq_livro = c.nu_seq_livro
  AND a.an_programa = '2010'
  AND a.nu_seq_prog_acao_distr = 1
  AND a.co_tp_entidade IN ('10','28','43')

GROUP BY a.sg_uf, c.co_tp_complemento,
DECODE(c.co_tp_complemento,'1','L','2','M','3','C')

ORDER BY a.sg_uf,c.co_tp_complemento;




-


Depois de tentar aplicar a tecnica parei aqui, mas ficou pior, com certeza
eu errei


-






SELECT

 a.sg_uf,c.co_tp_complemento
,DECODE(c.co_tp_complemento,'1','L','2','M','3','C')ds_tp_complemento
,SUM(NVL(a.qt_saldo_ano_anterior,0))qt_saldo_ano_anterior
,SUM(NVL(a.qt_recebido,0))qt_recebido
,SUM(NVL(remRec.qt_rem_recebido,0))qt_rem_recebido
,SUM(NVL(remEfe.qt_rem_efetuado,0))qt_rem_efetuado
,SUM(NVL(a.qt_saldo_ano_anterior,0) +
(NVL(a.qt_recebido,0)+NVL(remRec.qt_rem_recebido,0)+NVL(remEfe.qt_rem_efetuado,0)))
qt_total_livros

FROM simad_fnde.i_livro_pnl c  , simad_fnde.i_livro_distribuido_pnl a

INNER JOIN
(SELECT

r.an_programa,r.nu_seq_livro,r.nu_seq_destino,r.nu_seq_prog_acao_distr,
  sum(r.qt_remanejamento_recebido) qt_rem_recebido

 FROM simad_fnde.i_remanejamento_pnl r
 WHERE r.nu_seq_destino  0
   AND r.an_programa = '2010'
   AND r.nu_seq_prog_acao_distr = 1

GROUP BY r.an_programa, r.nu_seq_livro, r.nu_seq_destino,
r.nu_seq_prog_acao_distr)
remRec ON  remRec.nu_seq_livro = a.nu_seq_livro AND
remRec.nu_seq_destino = a.nu_seq_entidade


INNER JOIN
(SELECT

r.an_programa,r.nu_seq_livro,r.nu_seq_origem,r.nu_seq_prog_acao_distr,
  sum(r.qt_remanejamento_efetuado) qt_rem_efetuado

 FROM simad_fnde.i_remanejamento_pnl r

 WHERE r.nu_seq_origem  0
   AND r.an_programa = '2010'
   AND r.nu_seq_prog_acao_distr = 1

 GROUP BY r.an_programa, r.nu_seq_livro, r.nu_seq_origem,
r.nu_seq_prog_acao_distr)
 remEfe  ON  remEfe.nu_seq_livro = a.nu_seq_livro AND
remEfe.nu_seq_origem = a.nu_seq_entidade

WHERE a.nu_seq_livro = c.nu_seq_livro
  AND a.an_programa = '2010'
  AND a.nu_seq_prog_acao_distr = 1
  AND a.co_tp_entidade IN ('10','28','43')

GROUP BY a.sg_uf, c.co_tp_complemento,
DECODE(c.co_tp_complemento,'1','L','2','M','3','C')





UNION ALL





SELECT

 a.sg_uf,c.co_tp_complemento
,DECODE(c.co_tp_complemento,'1','L','2','M','3','C')ds_tp_complemento
,SUM(NVL(a.qt_saldo_ano_anterior,0))qt_saldo_ano_anterior
,SUM(NVL(a.qt_recebido,0))qt_recebido
,SUM(NVL(remRec.qt_rem_recebido,0))qt_rem_recebido
--,SUM(NVL(remEfe.qt_rem_efetuado,0))qt_rem_efetuado
--,SUM(NVL(a.qt_saldo_ano_anterior,0) +
(NVL(a.qt_recebido,0)+NVL(remRec.qt_rem_recebido,0)+NVL(remEfe.qt_rem_efetuado,0)))
qt_total_livros

FROM simad_fnde.i_livro_pnl c  , simad_fnde.i_livro_distribuido_pnl a

INNER JOIN
(SELECT

r.an_programa,r.nu_seq_livro,r.nu_seq_destino,r.nu_seq_prog_acao_distr,
  sum(r.qt_remanejamento_recebido) qt_rem_recebido

 FROM simad_fnde.i_remanejamento_pnl r
 WHERE r.nu_seq_destino  0
   AND r.an_programa = '2010'
  

Re: [pgbr-geral] Otimizar consulta com LEFT JOIN

2010-06-21 Por tôpico Mozart Hasse

- Original Message - 
From: pgbr-geral-requ...@listas.postgresql.org.br
To: pgbr-geral@listas.postgresql.org.br
Sent: Monday, June 21, 2010 4:34 PM
Subject: Digest pgbr-geral, volume 40, assunto 28


Send pgbr-geral mailing list submissions to
pgbr-geral@listas.postgresql.org.br

To subscribe or unsubscribe via the World Wide Web, visit
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral
or, via email, send a message with subject or body 'help' to
pgbr-geral-requ...@listas.postgresql.org.br

You can reach the person managing the list at
pgbr-geral-ow...@listas.postgresql.org.br

When replying, please edit your Subject line so it is more specific
than Re: Contents of pgbr-geral digest...


Tópicos de Hoje:

   1. PGCon Brasil 2010 (Alcione Benacchio)
   2. Select em tabela varchar (Jéckson E. Schwengber)
   3. Re: Otimizar consulta com LEFT JOIN (Eduardo Amaral)
   4. Tutorial em português para testar a replicação com hot
  standby do PostgreSQL 9.0 (Diogo Biazus)
   5. Re: PGCon Brasil 2010 (Leonardo Cezar)


--

Message: 1
Date: Mon, 21 Jun 2010 15:07:24 -0300
From: Alcione Benacchio benacc...@gmail.com
Subject: [pgbr-geral] PGCon Brasil 2010
To: Comunidade PostgreSQL Brasileira
pgbr-geral@listas.postgresql.org.br
Message-ID:
aanlktimb658xjcq4duitld_tpaguvuef11dkkhdx0...@mail.gmail.com
Content-Type: text/plain; charset=iso-8859-1

Olá,

Tem alguém na lista que é da organização e que tem informações sobre a PGCon
Brasil 2010?
Estou fazendo previsão orçamentária para o próximo semestre e gostaria saber
algumas informações.

Obrigado.

Att.

Alcione
-- Próxima Parte --
Um anexo em HTML foi limpo...
URL: 
http://listas.postgresql.org.br/pipermail/pgbr-geral/attachments/20100621/6d5fa898/attachment-0001.htm

--

Message: 2
Date: Thu, 17 Jun 2010 09:14:46 -0300
From: Jéckson E. Schwengber jeck...@codebuilder.com.br
Subject: [pgbr-geral] Select em tabela varchar
To: Comunidade PostgreSQL Brasileira
pgbr-geral@listas.postgresql.org.br
Message-ID: 4c1a11b6.7040...@codebuilder.com.br
Content-Type: text/plain; charset=iso-8859-1

Um anexo em HTML foi limpo...
URL: 
http://listas.postgresql.org.br/pipermail/pgbr-geral/attachments/20100617/ff4727f2/attachment-0001.htm

--

Message: 3
Date: Mon, 21 Jun 2010 15:45:13 -0300
From: Eduardo Amaral edu.ama...@gmail.com
Subject: Re: [pgbr-geral] Otimizar consulta com LEFT JOIN
To: Comunidade PostgreSQL Brasileira
pgbr-geral@listas.postgresql.org.br
Message-ID:
aanlktikzriyse06s0wmj31j9bde6cd35ujekno_6o...@mail.gmail.com
Content-Type: text/plain; charset=iso-8859-1

Mozar,

Depois de ler a técnica tentei de todo jeito mas não fui muito feliz...

A 1 Parte com Inner, ficou muito RAPIDO
Acho que fiz errado , na segunda parte pq piorou o tempo da query
anterior

essa é a query

(ja tomei de uns 8x0 dela)




---


SELECT

 a.sg_uf,c.co_tp_complemento
,DECODE(c.co_tp_complemento,'1','L','2','M','3','C')ds_tp_complemento
,SUM(NVL(a.qt_saldo_ano_anterior,0))qt_saldo_ano_anterior
,SUM(NVL(a.qt_recebido,0))qt_recebido
,SUM(NVL(remRec.qt_rem_recebido,0))qt_rem_recebido
,SUM(NVL(remEfe.qt_rem_efetuado,0))qt_rem_efetuado
,SUM(NVL(a.qt_saldo_ano_anterior,0) +
(NVL(a.qt_recebido,0)+NVL(remRec.qt_rem_recebido,0)+NVL(remEfe.qt_rem_efetuado,0)))
qt_total_livros

FROM simad.i_livro_pnl c  , simad.i_livro_distribuido_pnl a

LEFT OUTER JOIN

(SELECT
r.an_programa,r.nu_seq_livro,r.nu_seq_destino,r.nu_seq_prog_acao_distr,
  sum(r.qt_remanejamento_recebido) qt_rem_recebido

 FROM simad.i_remanejamento_pnl r
 WHERE r.nu_seq_destino  0
   AND r.an_programa = '2010'
   AND r.nu_seq_prog_acao_distr = 1

GROUP BY r.an_programa, r.nu_seq_livro, r.nu_seq_destino,
r.nu_seq_prog_acao_distr)remRec

ON  remRec.nu_seq_livro = a.nu_seq_livro AND remRec.nu_seq_destino =
a.nu_seq_entidade


LEFT OUTER JOIN

(SELECT
r.an_programa,r.nu_seq_livro,r.nu_seq_origem,r.nu_seq_prog_acao_distr,
  sum(r.qt_remanejamento_efetuado) qt_rem_efetuado

 FROM simad.i_remanejamento_pnl r

 WHERE r.nu_seq_origem  0
   AND r.an_programa = '2010'
   AND r.nu_seq_prog_acao_distr = 1

 GROUP BY r.an_programa, r.nu_seq_livro, r.nu_seq_origem,
r.nu_seq_prog_acao_distr)remEfe

ON  remEfe.nu_seq_livro = a.nu_seq_livro

AND remEfe.nu_seq_origem = a.nu_seq_entidade

WHERE a.nu_seq_livro = c.nu_seq_livro
  AND a.an_programa = '2010'
  AND a.nu_seq_prog_acao_distr = 1
  AND a.co_tp_entidade IN ('10','28','43')

GROUP BY a.sg_uf, c.co_tp_complemento,
DECODE(c.co_tp_complemento,'1','L','2','M','3','C')

ORDER BY a.sg_uf,c.co_tp_complemento;




-


Depois de tentar aplicar a tecnica parei aqui, mas ficou pior, com certeza
eu errei


-






SELECT

[pgbr-geral] Otimizar consulta com LEFT JOIN

2010-06-21 Por tôpico Mozart Hasse
Olá Eduardo,

 Depois de ler a técnica tentei de todo jeito mas não fui muito feliz...

 Vamos mudar o placar então.
 Não conheço a regra de negócio dessas tabelas, mas pelo que entendi são 
duas
 subconsultas independentes, sendo assim, vejamos:
 * o segundo UNION não pode ter os INNER que você colocou no primeiro, basta
 ter o NOT EXISTS.
 * são DOIS outer joins, logo você pode precisar de até 4 subconsultas (3
 unions)
 Então sua consulta ficará:
 1. Consulta original trocando OUTER por INNER
 2. Consulta original trocando OUTER por INNER no primeiro LEFT e trocando o
 segundo LEFT por um WHERE NOT EXISTS
 3. Consulta original trocando OUTER por INNER no segundo LEFT e trocando o
 primeiro LEFT por um WHERE NOT EXISTS
 4. Consulta original sem OUTER nem INNER, e na cláusula WHERE você coloca 
um
 NOT EXISTS para o primeiro LEFT e outro NOT EXISTS para o segundo

Mozart Hasse
(desculpem o vacilo no botão enviar da mensagem anterior) 

___
pgbr-geral mailing list
pgbr-geral@listas.postgresql.org.br
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral


Re: [pgbr-geral] Otimizar consulta com LEFT JOIN

2010-05-20 Por tôpico Mozart Hasse
Oi Marcel,

 Não ficou muito claro para mim a reescrita de uma consulta.
 Como eu faria numa consulta como esta abaixo???

*Assumindo* que turmas_ofertas_professores tem o campo turma_oferta_id não
nulo
*e* que *todo* o professor tem uma referência à tabela pessoas, ficaria:

SELECT tof.id AS turma_oferta_id, tpo.id AS turma_professor_id, pf.id AS
professor_id, pf.cod_prof, ps.id, ps.nome_pessoa, sum(tpo.carga_horaria) AS
carga_horaria, sum(tpo.carga_horaria) * 0.2::double precision AS
horas_preparacao, d.id AS disciplina_id, d.cod_disciplina,
d.nome_disciplina, tof.nr_vagas, tof.cod_turma, tof.periodo_id
FROM turmas_ofertas tof
INNER JOIN disciplinas d ON tof.disciplina_id = d.id
INNER JOIN turmas_ofertas_professores tpo ON tpo.turma_oferta_id = tof.id
INNER JOIN professores pf ON tpo.professor_id = pf.id
INNER JOIN pessoas ps ON pf.pessoa_id = ps.id
GROUP BY tpo.id, tpo.carga_horaria, tof.id, tof.cod_turma, tof.nr_vagas,
tof.periodo_id, d.id, d.cod_disciplina, d.nome_disciplina, pf.id,
pf.cod_prof, ps.id, ps.nome_pessoa;*

UNION ALL

SELECT tof.id AS turma_oferta_id, tpo.id AS turma_professor_id, pf.id AS
professor_id, pf.cod_prof, ps.id, ps.nome_pessoa, sum(tpo.carga_horaria) AS
carga_horaria, sum(tpo.carga_horaria) * 0.2::double precision AS
horas_preparacao, d.id AS disciplina_id, d.cod_disciplina,
d.nome_disciplina, tof.nr_vagas, tof.cod_turma, tof.periodo_id
FROM turmas_ofertas tof
INNER JOIN disciplinas d ON tof.disciplina_id = d.id
WHERE NOT EXISTS( SELECT 1 FROM turmas_ofertas_professores tpo WHERE
tpo.turma_oferta_id = tof.id)

É de se esperar um ganho bem significativo com essa otimização.

Caso as premissas acima não sejam válidas, verifique se sua modelagem
realmente precisa ser assim e se prepare para ter até 7 UNION ALL seguindo um
critério similar ao exposto acima.

Mozart Hasse


___
pgbr-geral mailing list
pgbr-geral@listas.postgresql.org.br
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral


Re: [pgbr-geral] Otimizar consulta com LEFT JOIN

2010-05-20 Por tôpico Marcel Araujo
Aham, muito obrigado pela explicação. Irei testar daqui a pouco e darei
retorno.

-- 
Abraços..

Marcel Araujo
System Analyst
Developer Java/PHP/RIA
Linux User #490101
http://br.linkedin.com/in/marcelaraujo
http://www.twitter.com/marcelaraujo
http://marcelaraujo.tumblr.com/
http://www.marcelaraujo.com
http://www.marcelaraujo.com.br
___
pgbr-geral mailing list
pgbr-geral@listas.postgresql.org.br
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral


Re: [pgbr-geral] Otimizar consulta com LEFT JOIN

2010-05-20 Por tôpico Marcel Araujo
ahahahahaha, tô em estado de graça!

Meu amigo, consegui reduzir uma consulta de faturamento de 67 segundos para
apenas 10 segundos e podendo melhor ainda mais.

-- 
Abraços..

Marcel Araujo
System Analyst
Developer Java/PHP/RIA
Linux User #490101
http://br.linkedin.com/in/marcelaraujo
http://www.twitter.com/marcelaraujo
http://marcelaraujo.tumblr.com/
http://www.marcelaraujo.com
http://www.marcelaraujo.com.br
___
pgbr-geral mailing list
pgbr-geral@listas.postgresql.org.br
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral


Re: [pgbr-geral] Otimizar consulta com LEFT JOIN

2010-05-20 Por tôpico Priscila Cardoso Gonçalves
Olá Mozart,
estava tentando reescrever uma consulta agora a pouco, tentando aplicar
essas sugestões.

Porém, se eu executasse desse jeito que está no exemplo, ele não reclamaria
que está faltando entrada para a tabela ps e pf no segundo select? E se eu
colocasse os inners para essas tabelas não precisaria fazer o UNION ALL...
fiquei confusa.

-- 
Atenciosamente,
Priscila Cardoso Gonçalves
http://meadiciona.com.br/prinity
Linux User: #415920

Considere a proteção ao meio ambiente antes de imprimir esse e-mail.


Em 20 de maio de 2010 12:39, Mozart Hasse mozart.ha...@usa.net escreveu:

 Oi Marcel,

  Não ficou muito claro para mim a reescrita de uma consulta.
  Como eu faria numa consulta como esta abaixo???

 *Assumindo* que turmas_ofertas_professores tem o campo turma_oferta_id não
 nulo
 *e* que *todo* o professor tem uma referência à tabela pessoas, ficaria:

 SELECT tof.id AS turma_oferta_id, tpo.id AS turma_professor_id, pf.id AS
 professor_id, pf.cod_prof, ps.id, ps.nome_pessoa, sum(tpo.carga_horaria)
 AS
 carga_horaria, sum(tpo.carga_horaria) * 0.2::double precision AS
 horas_preparacao, d.id AS disciplina_id, d.cod_disciplina,
 d.nome_disciplina, tof.nr_vagas, tof.cod_turma, tof.periodo_id
 FROM turmas_ofertas tof
 INNER JOIN disciplinas d ON tof.disciplina_id = d.id
 INNER JOIN turmas_ofertas_professores tpo ON tpo.turma_oferta_id = tof.id
 INNER JOIN professores pf ON tpo.professor_id = pf.id
 INNER JOIN pessoas ps ON pf.pessoa_id = ps.id
 GROUP BY tpo.id, tpo.carga_horaria, tof.id, tof.cod_turma, tof.nr_vagas,
 tof.periodo_id, d.id, d.cod_disciplina, d.nome_disciplina, pf.id,
 pf.cod_prof, ps.id, ps.nome_pessoa;*

 UNION ALL

 SELECT tof.id AS turma_oferta_id, tpo.id AS turma_professor_id, pf.id AS
 professor_id, pf.cod_prof, ps.id, ps.nome_pessoa, sum(tpo.carga_horaria)
 AS
 carga_horaria, sum(tpo.carga_horaria) * 0.2::double precision AS
 horas_preparacao, d.id AS disciplina_id, d.cod_disciplina,
 d.nome_disciplina, tof.nr_vagas, tof.cod_turma, tof.periodo_id
 FROM turmas_ofertas tof
 INNER JOIN disciplinas d ON tof.disciplina_id = d.id
 WHERE NOT EXISTS( SELECT 1 FROM turmas_ofertas_professores tpo WHERE
 tpo.turma_oferta_id = tof.id)

 É de se esperar um ganho bem significativo com essa otimização.

 Caso as premissas acima não sejam válidas, verifique se sua modelagem
 realmente precisa ser assim e se prepare para ter até 7 UNION ALL seguindo
 um
 critério similar ao exposto acima.

 Mozart Hasse


 ___
 pgbr-geral mailing list
 pgbr-geral@listas.postgresql.org.br
 https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral

___
pgbr-geral mailing list
pgbr-geral@listas.postgresql.org.br
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral


Re: [pgbr-geral] Otimizar consulta com LEFT JOIN

2010-05-20 Por tôpico Mozart Hasse
Oi Priscila,

 Subject: Re: [pgbr-geral] Otimizar consulta com LEFT JOIN
 To: Comunidade PostgreSQL Brasileira

 Porém, se eu executasse desse jeito que está no exemplo, ele não 
 reclamaria
 que está faltando entrada para a tabela ps e pf no segundo select? E se eu
 colocasse os inners para essas tabelas não precisaria fazer o UNION ALL...
 fiquei confusa.

No segundo select as tabelas PS e PF não precisam ser consultadas porque o 
objetivo da segunda consulta é trazer apenas os registros que não têm 
valores na tabela que as liga com a tabela principal. Essa é a idéia que 
torna reescrever a query algo vantajoso: ao invés de consultar registro a 
registro para ver se tem ou não tem correspondência em cada uma das tabelas 
filhas, eu divido a consulta em duas partes: uma traz primeiro todos os 
registros que *tenham* todas as tabelas filhas, depois junto isso (via UNION 
ALL para não precisar conferir duplicidades) com todos os registros que *não 
têm* nenhum registro nas tabelas filhas. Pela forma como as tabelas se 
interligam, neste caso eu não preciso consultar todas as tabelas filhas, 
pois se não existir a correspondência em uma delas eu já deduzo que as 
outras não se aplicam.

Atenciosamente,

Mozart Hasse 


___
pgbr-geral mailing list
pgbr-geral@listas.postgresql.org.br
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral


Re: [pgbr-geral] Otimizar consulta com LEFT JOIN

2010-05-19 Por tôpico Mozart Hasse
Mateus,

Cuidado ao montar as combinações, há repetições na sua consulta. Faltou
também NOT EXISTS nas tabelas que não sofreram INNER JOIN:

-- com B sem C
SELECT campoA, campoB, null as c 
FROM a INNER JOIN b ON (a.id= b.id)
WHERE NOT EXISTS (SELECT 1 FROM c WHERE a.id= c.id)

UNION all 

-- sem B sem C
SELECT campoA, null as b, null as c FROM a WHERE 
NOT EXISTS (SELECT 1 FROM b WHERE a.id= b.id) 
AND NOT EXISTS (SELECT 1 FROM c WHERE a.id= c.id)

UNION all

-- sem B com C
SELECT campoA, null as b, campoC 
FROM a INNER JOIN c ON (a.id= c.id)
WHERE NOT EXISTS (SELECT 1 FROM b WHERE a.id= b.id) 

UNION all

-- com B com C
SELECT campoA, campoB, campoC as c FROM a 
INNER JOIN b ON (a.id= b.id)
INNER JOIN c ON (a.id= c.id)


Mozart

-- Original Message --
 From: mateusgra mateus...@bol.com.br
 Subject: Re: [pgbr-geral] Otimizar consulta com LEFT JOIN
 
 Seria assim:
 
 SELECT  campoA, campoB, null as c FROM a INNER JOIN b ON (a.id= b.id)
 UNION all 
 SELECT  campoA, null as b, null as c FROM a WHERE NOT EXISTS (SELECT 1
 FROM b WHERE a.id= b.id)
 UNION all
 SELECT  campoA, null as b, campoC FROM a INNER JOIN c ON (a.id= c.id)
 UNION all
 SELECT  campoA, null as b, null as c FROM a WHERE NOT EXISTS (SELECT 1
 FROM c WHERE a.id= c.id)
 
 Ocorreu duas linhas por registro.


___
pgbr-geral mailing list
pgbr-geral@listas.postgresql.org.br
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral


Re: [pgbr-geral] Otimizar consulta com LEFT JOIN

2010-05-19 Por tôpico Benedito A. Cruz


   Não sei se minha pergunta é boba, mas:

  Porque fazer desse jeito é mais eficiente do que fazer um LEFT JOIN?


[]s

   Bene


Em 19/5/2010 12:37, Mozart Hasse escreveu:
 Mateus,

 Cuidado ao montar as combinações, há repetições na sua consulta. Faltou
 também NOT EXISTS nas tabelas que não sofreram INNER JOIN:

 -- com B sem C
 SELECT campoA, campoB, null as c
 FROM a INNER JOIN b ON (a.id= b.id)
 WHERE NOT EXISTS (SELECT 1 FROM c WHERE a.id= c.id)

 UNION all

 -- sem B sem C
 SELECT campoA, null as b, null as c FROM a WHERE
 NOT EXISTS (SELECT 1 FROM b WHERE a.id= b.id)
 AND NOT EXISTS (SELECT 1 FROM c WHERE a.id= c.id)

 UNION all

 -- sem B com C
 SELECT campoA, null as b, campoC
 FROM a INNER JOIN c ON (a.id= c.id)
 WHERE NOT EXISTS (SELECT 1 FROM b WHERE a.id= b.id)

 UNION all

 -- com B com C
 SELECT campoA, campoB, campoC as c FROM a
 INNER JOIN b ON (a.id= b.id)
 INNER JOIN c ON (a.id= c.id)


 Mozart

 -- Original Message --

 From: mateusgramateus...@bol.com.br
 Subject: Re: [pgbr-geral] Otimizar consulta com LEFT JOIN

 Seria assim:

 SELECT  campoA, campoB, null as c FROM a INNER JOIN b ON (a.id= b.id)
 UNION all
 SELECT  campoA, null as b, null as c FROM a WHERE NOT EXISTS (SELECT 1
 FROM b WHERE a.id= b.id)
 UNION all
 SELECT  campoA, null as b, campoC FROM a INNER JOIN c ON (a.id= c.id)
 UNION all
 SELECT  campoA, null as b, null as c FROM a WHERE NOT EXISTS (SELECT 1
 FROM c WHERE a.id= c.id)

 Ocorreu duas linhas por registro.
  

 ___
 pgbr-geral mailing list
 pgbr-geral@listas.postgresql.org.br
 https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral





-- 
This message has been scanned for viruses and
dangerous content by MailScanner, and is
believed to be clean.

___
pgbr-geral mailing list
pgbr-geral@listas.postgresql.org.br
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral


Re: [pgbr-geral] Otimizar consulta com LEFT JOIN

2010-05-19 Por tôpico vinicius perroni
Sim amigo por exemplo a query que estava tentando melhorar demorava
uns 25segundos com left join passando a usar a técnica do Mozart ela
passou a executar em no max 3segundos.

Abaixo segue a query modificada.

SELECT
codigofab,
descricao,
prazo,
quantidade,
vlr_bruto_genuina,
desconto_genuina,
vlr_liq_genuina,
descricao_orcamento,
orcamento_total,
Join(nfiscal) AS nfiscal,
SUM(num_ocompra) AS num_ocompra
FROM
(
SELECT
po.codigofab, po.descricao, po.prazo, po.quantidade, 
po.vlr_bruto_genuina,
po.desconto_genuina, po.vlr_liq_genuina, s_o.descr_situacao as
descricao_orcamento,
(po.vlr_liq_genuina * po.quantidade) as orcamento_total,
null as nfiscal, 0 as num_ocompra
FROM
fornecimentos.pecas_orcamentos po
INNER JOIN fornecimentos.situacoes s_o ON po.cod_situacao = 
s_o.id_situacao
--LEFT JOIN fornecimentos.ocompras oc ON oc.cod_orcamento =
po.cod_orcamento AND oc.cod_situacao  16
--LEFT JOIN fornecimentos.pecas_ocompras pc ON pc.cod_ocompra =
oc.id_ocompra AND pc.codigofab = po.codigofab
--LEFT JOIN fornecimentos.nfiscais nf ON pc.cod_ocompra =
nf.cod_ocompra AND nf.cod_situacao  18
--LEFT JOIN fornecimentos.pecas_nfiscal pf ON 
pf.cod_nota_fiscal =
nf.id_nfiscal AND pf.cod_peca_ocompra = pc.id_peca_ocompra
WHERE
po.cod_orcamento = 1090857

UNION ALL

SELECT
po.codigofab, po.descricao, po.prazo, po.quantidade, 
po.vlr_bruto_genuina,
po.desconto_genuina, po.vlr_liq_genuina, s_o.descr_situacao as
descricao_orcamento,
(po.vlr_liq_genuina * po.quantidade) as orcamento_total,
null as nfiscal, oc.num_ocompra
FROM
fornecimentos.pecas_orcamentos po
INNER JOIN fornecimentos.situacoes s_o ON po.cod_situacao = 
s_o.id_situacao
INNER JOIN fornecimentos.ocompras oc ON oc.cod_orcamento =
po.cod_orcamento AND oc.cod_situacao  16
INNER JOIN fornecimentos.pecas_ocompras pc ON pc.cod_ocompra =
oc.id_ocompra AND pc.codigofab = po.codigofab
--LEFT JOIN fornecimentos.nfiscais nf ON pc.cod_ocompra =
nf.cod_ocompra AND nf.cod_situacao  18
--LEFT JOIN fornecimentos.pecas_nfiscal pf ON 
pf.cod_nota_fiscal =
nf.id_nfiscal AND pf.cod_peca_ocompra = pc.id_peca_ocompra
WHERE
po.cod_orcamento = 1090857

UNION ALL

SELECT
po.codigofab, po.descricao, po.prazo, po.quantidade, 
po.vlr_bruto_genuina,
po.desconto_genuina, po.vlr_liq_genuina, s_o.descr_situacao as
descricao_orcamento,
(po.vlr_liq_genuina * po.quantidade) as orcamento_total,
nf.nfiscal, oc.num_ocompra
FROM
fornecimentos.pecas_orcamentos po
INNER JOIN fornecimentos.situacoes s_o ON po.cod_situacao = 
s_o.id_situacao
INNER JOIN fornecimentos.ocompras oc ON oc.cod_orcamento =
po.cod_orcamento AND oc.cod_situacao  16
INNER JOIN fornecimentos.pecas_ocompras pc ON pc.cod_ocompra =
oc.id_ocompra AND pc.codigofab = po.codigofab
INNER JOIN fornecimentos.nfiscais nf ON oc.id_ocompra =
nf.cod_ocompra AND nf.cod_situacao  18
--INNER JOIN fornecimentos.pecas_nfiscal pf ON 
pf.cod_nota_fiscal =
nf.id_nfiscal AND pf.cod_peca_ocompra = pc.id_peca_ocompra
WHERE
po.cod_orcamento = 1090857

)as pecas

GROUP BY
codigofab,
descricao,
prazo,
quantidade,
vlr_bruto_genuina,
desconto_genuina,
vlr_liq_genuina,
descricao_orcamento,
orcamento_total



Vinicius Perroni
___
pgbr-geral mailing list
pgbr-geral@listas.postgresql.org.br
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral


Re: [pgbr-geral] Otimizar consulta com LEFT JOIN

2010-05-19 Por tôpico Fábio Telles Rodriguez


 Aplique a idéia de usar UNION ALL. Isso funciona em qualquer servidor SQL e
 nunca vi piorar o desempenho da consulta. O que faço é o seguinte: para
 CADA
 LEF OUTER JOIN da sua consulta, substitua por duas cópias da mesma query
 separadas por UNION ALL (não union, tem de ser UNION ALL), sendo que numa
 delas você vai trocar o LEFT OUTER JOIN por um INNER JOIN e na outra você
 vai tirar fora o LEFT OUTER da tabela e incluir lá na cláusula WHERE a
 condição AND NOT EXISTS(SELECT 1 FROM suatabeladoleft WHERE joins que
 estavam no LEFT). Provavelmente você vai notar que ao por INNER na tabela
 que antes era OUTER você poderá trocar um monte de OUTERs por INNERs nas
 tabelas filhas dela também, o que ajudará ainda mais a melhorar o
 desempenho.

 A implicação disso é que, se tua query tem 2 LEFT OUTER, a combinação de
 todos com todos vai resultar em 4 consultas separadas por UNION ALL. Nunca
 precisei de mais do que 8. Não se assuste porque valerá a pena.
 Sua query vai ficar grande, porém mesmo seis vezes maior ainda ficará muito
 mais rápida que a original. Faço isso aqui direto com ótimos resultados.
 Minha aplicação não sofreu nenhuma alteração na modelagem por conta
 disso, porém com essas trocas para UNION ALL, o LEFT OUTER JOIN está
 virando
 lenda por aqui, praticamente ninguém mais usa.


Hey, esta é uma dica que deveria ser documentada em algum lugar. Dava um bom
texto para o wiki ou para um blog.

Muito bom mesmo.

[]s
-- 
blog: http://www.midstorm.org/~telles/
e-mail / jabber: fabio.tel...@gmail.com
___
pgbr-geral mailing list
pgbr-geral@listas.postgresql.org.br
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral


Re: [pgbr-geral] Otimizar consulta com LEFT JOIN

2010-05-19 Por tôpico Mozart Hasse
Benedito,

   Não sei se minha pergunta é boba, mas:
Porque fazer desse jeito é mais eficiente do que fazer um LEFT JOIN?

A pergunta não é boba não, na realidade a explicação não é nada trivial.
A resposta mais simples e curta que posso dar é: esse jeito (UNION ALL + 
INNER + NOT EXISTS) é mais eficiente porque o otimizador não tem 
inteligência suficiente para notar que são equivalentes.
Em alguns casos simples, alguns bancos de dados fazem a conversão 
automaticamente e procuram por um plano otimizado. Em casos mais 
complicados, nem todo otimizador consegue.

Talvez para você ainda reste a pergunta tá mas por quê fazer 4 unions é 
mais rápido que um OUTER?. Neste caso a resposta também não é trivial:
É que ao dividir a consulta em 4 menores, o servidor pode usar um índice 
diferente (muitas vezes de uma das tabelas filhas) para cada uma das 
subconsultas ao invés de percorrer a tabela principal sequencialmente. É 
exatamente essa habilidade de escolher índices pelo volume da tabela filha 
que pode tornar a consulta infinitamente mais rápida.

Atenciosamente,

Mozart Hasse 


___
pgbr-geral mailing list
pgbr-geral@listas.postgresql.org.br
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral


Re: [pgbr-geral] Otimizar consulta com LEFT JOIN

2010-05-19 Por tôpico Prof. Benedito A. Cruz
Muito boa explicação, obrigado!

Em 19/05/2010 19:55, Mozart Hasse escreveu:
 Benedito,


Não sei se minha pergunta é boba, mas:
 Porque fazer desse jeito é mais eficiente do que fazer um LEFT JOIN?
  
 A pergunta não é boba não, na realidade a explicação não é nada trivial.
 A resposta mais simples e curta que posso dar é: esse jeito (UNION ALL +
 INNER + NOT EXISTS) é mais eficiente porque o otimizador não tem
 inteligência suficiente para notar que são equivalentes.
 Em alguns casos simples, alguns bancos de dados fazem a conversão
 automaticamente e procuram por um plano otimizado. Em casos mais
 complicados, nem todo otimizador consegue.

 Talvez para você ainda reste a pergunta tá mas por quê fazer 4 unions é
 mais rápido que um OUTER?. Neste caso a resposta também não é trivial:
 É que ao dividir a consulta em 4 menores, o servidor pode usar um índice
 diferente (muitas vezes de uma das tabelas filhas) para cada uma das
 subconsultas ao invés de percorrer a tabela principal sequencialmente. É
 exatamente essa habilidade de escolher índices pelo volume da tabela filha
 que pode tornar a consulta infinitamente mais rápida.

 Atenciosamente,

 Mozart Hasse


 ___
 pgbr-geral mailing list
 pgbr-geral@listas.postgresql.org.br
 https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral





-- 
This message has been scanned for viruses and
dangerous content by MailScanner, and is
believed to be clean.

___
pgbr-geral mailing list
pgbr-geral@listas.postgresql.org.br
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral


Re: [pgbr-geral] Otimizar consulta com LEFT JOIN

2010-05-19 Por tôpico Marcel Araujo
Não ficou muito claro para mim a reescrita de uma consulta.

Como eu faria numa consulta como esta abaixo???

*CREATE OR REPLACE VIEW vw_ch_professores_turmas_ofertas AS
SELECT tof.id AS turma_oferta_id, tpo.id AS turma_professor_id, pf.id AS
professor_id, pf.cod_prof, ps.id, ps.nome_pessoa, sum(tpo.carga_horaria) AS
carga_horaria, sum(tpo.carga_horaria) * 0.2::double precision AS
horas_preparacao, d.id AS disciplina_id, d.cod_disciplina,
d.nome_disciplina, tof.nr_vagas, tof.cod_turma, tof.periodo_id
  FROM turmas_ofertas tof
  JOIN disciplinas d ON tof.disciplina_id = d.id
  LEFT JOIN turmas_ofertas_professores tpo ON tpo.turma_oferta_id = tof.id
  LEFT JOIN professores pf ON tpo.professor_id = pf.id
  LEFT JOIN pessoas ps ON pf.pessoa_id = ps.id
 GROUP BY tpo.id, tpo.carga_horaria, tof.id, tof.cod_turma, tof.nr_vagas,
tof.periodo_id, d.id, d.cod_disciplina, d.nome_disciplina, pf.id,
pf.cod_prof, ps.id, ps.nome_pessoa;*

-- 
Abraços..

Marcel Araujo
System Analyst
Developer Java/PHP/RIA
Linux User #490101
http://br.linkedin.com/in/marcelaraujo
http://www.twitter.com/marcelaraujo
http://marcelaraujo.tumblr.com/
___
pgbr-geral mailing list
pgbr-geral@listas.postgresql.org.br
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral


Re: [pgbr-geral] Otimizar consulta com LEFT JOIN

2010-05-18 Por tôpico vinicius perroni
Obrigado pelas dicas tanto a do Marcos que faz pensar que quando
iniciar um projeto novo já planejar essas functions e a solução do
Mozart que implementei e deu certo a query demorava 25segundos caiu
para 2 3 segundos.
vlw...

Att
Vinicius Perroni
___
pgbr-geral mailing list
pgbr-geral@listas.postgresql.org.br
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral


Re: [pgbr-geral] Otimizar consulta com LEFT JOIN

2010-05-18 Por tôpico mateusgra

Seria assim:

CREATE VIEW vw_uniao as 
SELECT  campoA, campoB, null as c FROM a INNER JOIN b ON (a.id= b.id)
UNION ALL 
SELECT  campoA, campoB, null as c FROM a WHERE NOT EXISTS (SELECT 1 FROM a
WHERE a.id= b.id)
UNION ALL
SELECT  campoA, null as b, campoC FROM a INNER JOIN c ON (a.id= c.id)
UNION ALL 
SELECT  campoA, null as b, campoC FROM a WHERE NOT EXISTS (SELECT 1 FROM a
WHERE a.id= c.id)

Ocorreu duas linhas por regitros quando  tem registro so em A e C ou A e B. 


Mozart Hasse wrote:
 
 Olá Vinicius,
 
 From: vinicius perroni vinicius...@gmail.com
 Subject: [pgbr-geral] Otimizar consulta com LEFT JOIN
 
 Estou com um velho problema uma consulta minha utiliza muitos LEFT
 JOINS tornandoa lenta demais.
  
 A consulta é mais ou menos assim tenho uma tabela de orçamentos, uma
 de ordens de compras e outra de Notas Fiscas, três tabelas sendo o
 unico registro que certamente existe é o orçamento. Junto elas com
 LEFT JOIN ...
  
 Pensei em usar UNION mas ainda não realizei testes alguem tem alguma
 ideia para substituir os LEFT JOINS e otimizar a consulta?
 
 Aplique a idéia de usar UNION ALL. Isso funciona em qualquer servidor SQL
 e
 nunca vi piorar o desempenho da consulta. O que faço é o seguinte: para
 CADA
 LEF OUTER JOIN da sua consulta, substitua por duas cópias da mesma query
 separadas por UNION ALL (não union, tem de ser UNION ALL), sendo que numa
 delas você vai trocar o LEFT OUTER JOIN por um INNER JOIN e na outra você
 vai tirar fora o LEFT OUTER da tabela e incluir lá na cláusula WHERE a
 condição AND NOT EXISTS(SELECT 1 FROM suatabeladoleft WHERE joins que
 estavam no LEFT). Provavelmente você vai notar que ao por INNER na tabela
 que antes era OUTER você poderá trocar um monte de OUTERs por INNERs nas
 tabelas filhas dela também, o que ajudará ainda mais a melhorar o
 desempenho.
 
 A implicação disso é que, se tua query tem 2 LEFT OUTER, a combinação de
 todos com todos vai resultar em 4 consultas separadas por UNION ALL. Nunca
 precisei de mais do que 8. Não se assuste porque valerá a pena.
 Sua query vai ficar grande, porém mesmo seis vezes maior ainda ficará
 muito
 mais rápida que a original. Faço isso aqui direto com ótimos resultados.
 Minha aplicação não sofreu nenhuma alteração na modelagem por conta
 disso, porém com essas trocas para UNION ALL, o LEFT OUTER JOIN está
 virando
 lenda por aqui, praticamente ninguém mais usa.
 
 Atenciosamente,
 
 Mozart Hasse
 
 
 ___
 pgbr-geral mailing list
 pgbr-geral@listas.postgresql.org.br
 https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral
 
 

-- 
View this message in context: 
http://old.nabble.com/Otimizar-consulta-com-LEFT-JOIN-tp28583265p28604012.html
Sent from the PostgreSQL - Brasil mailing list archive at Nabble.com.

___
pgbr-geral mailing list
pgbr-geral@listas.postgresql.org.br
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral


Re: [pgbr-geral] Otimizar consulta com LEFT JOIN

2010-05-18 Por tôpico mateusgra

Correção:

Seria assim:

SELECT  campoA, campoB, null as c FROM a INNER JOIN b ON (a.id= b.id)
UNION all 
SELECT  campoA, null as b, null as c FROM a WHERE NOT EXISTS (SELECT 1
FROM b WHERE a.id= b.id)
UNION all
SELECT  campoA, null as b, campoC FROM a INNER JOIN c ON (a.id= c.id)
UNION all
SELECT  campoA, null as b, null as c FROM a WHERE NOT EXISTS (SELECT 1
FROM c WHERE a.id= c.id)

Ocorreu duas linhas por registro.


mateusgra wrote:
 
 Seria assim:
 
 CREATE VIEW vw_uniao as 
 SELECT  campoA, campoB, null as c FROM a INNER JOIN b ON (a.id= b.id)
 UNION ALL 
 SELECT  campoA, campoB, null as c FROM a WHERE NOT EXISTS (SELECT 1 FROM a
 WHERE a.id= b.id)
 UNION ALL
 SELECT  campoA, null as b, campoC FROM a INNER JOIN c ON (a.id= c.id)
 UNION ALL 
 SELECT  campoA, null as b, campoC FROM a WHERE NOT EXISTS (SELECT 1 FROM a
 WHERE a.id= c.id)
 
 Ocorreu duas linhas por regitros quando  tem registro so em A e C ou A e
 B. 
 
 
 Mozart Hasse wrote:
 
 Olá Vinicius,
 
 From: vinicius perroni vinicius...@gmail.com
 Subject: [pgbr-geral] Otimizar consulta com LEFT JOIN
 
 Estou com um velho problema uma consulta minha utiliza muitos LEFT
 JOINS tornandoa lenta demais.
  
 A consulta é mais ou menos assim tenho uma tabela de orçamentos, uma
 de ordens de compras e outra de Notas Fiscas, três tabelas sendo o
 unico registro que certamente existe é o orçamento. Junto elas com
 LEFT JOIN ...
  
 Pensei em usar UNION mas ainda não realizei testes alguem tem alguma
 ideia para substituir os LEFT JOINS e otimizar a consulta?
 
 Aplique a idéia de usar UNION ALL. Isso funciona em qualquer servidor SQL
 e
 nunca vi piorar o desempenho da consulta. O que faço é o seguinte: para
 CADA
 LEF OUTER JOIN da sua consulta, substitua por duas cópias da mesma query
 separadas por UNION ALL (não union, tem de ser UNION ALL), sendo que numa
 delas você vai trocar o LEFT OUTER JOIN por um INNER JOIN e na outra você
 vai tirar fora o LEFT OUTER da tabela e incluir lá na cláusula WHERE a
 condição AND NOT EXISTS(SELECT 1 FROM suatabeladoleft WHERE joins que
 estavam no LEFT). Provavelmente você vai notar que ao por INNER na
 tabela
 que antes era OUTER você poderá trocar um monte de OUTERs por INNERs nas
 tabelas filhas dela também, o que ajudará ainda mais a melhorar o
 desempenho.
 
 A implicação disso é que, se tua query tem 2 LEFT OUTER, a combinação de
 todos com todos vai resultar em 4 consultas separadas por UNION ALL.
 Nunca
 precisei de mais do que 8. Não se assuste porque valerá a pena.
 Sua query vai ficar grande, porém mesmo seis vezes maior ainda ficará
 muito
 mais rápida que a original. Faço isso aqui direto com ótimos resultados.
 Minha aplicação não sofreu nenhuma alteração na modelagem por conta
 disso, porém com essas trocas para UNION ALL, o LEFT OUTER JOIN está
 virando
 lenda por aqui, praticamente ninguém mais usa.
 
 Atenciosamente,
 
 Mozart Hasse
 
 
 ___
 pgbr-geral mailing list
 pgbr-geral@listas.postgresql.org.br
 https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral
 
 
 
 

-- 
View this message in context: 
http://old.nabble.com/Otimizar-consulta-com-LEFT-JOIN-tp28583265p28604052.html
Sent from the PostgreSQL - Brasil mailing list archive at Nabble.com.

___
pgbr-geral mailing list
pgbr-geral@listas.postgresql.org.br
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral


[pgbr-geral] Otimizar consulta com LEFT JOIN

2010-05-17 Por tôpico vinicius perroni
Bom dia a todos.

Estou com um velho problema uma consulta minha utiliza muitos LEFT
JOINS tornandoa lenta demais.

A consulta é mais ou menos assim tenho uma tabela de orçamentos, uma
de ordens de compras e outra de Notas Fiscas, três tabelas sendo o
unico registro que certamente existe é o orçamento. Junto elas com
LEFT JOIN ...

Pensei em usar UNION mas ainda não realizei testes alguem tem alguma
ideia para substituir os LEFT JOINS e otimizar a consulta?


Att
Vinicius Perroni
___
pgbr-geral mailing list
pgbr-geral@listas.postgresql.org.br
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral


Re: [pgbr-geral] Otimizar consulta com LEFT JOIN

2010-05-17 Por tôpico vinicius perroni
Obrigado é um boa alternativa esta sua. (Só não sei se meu chefe vai
deixar eu sair criando funções na base de dados hehehe mas isso é
outro problema)

Obrigado pela ajuda.

Em 17 de maio de 2010 11:27, Marcos - GMail lgerardlu...@gmail.com escreveu:
 Tu pode fazer o seguinte: Se eu entendi bem, tu precisa de informações de
 diversas tabelas e o uso do left join. Vou te dar um exemplo pratico do que
 eu faço:

 Eu tenho uma tabela
 Orcamento(Mestre)
 OrcamentoItem(Detalhe)

 Nas tabelas acima eu uso o left join, entao:
 Select *
 From Orcamento left join OrcamentoItem on Orcamento.id =
 OrcamentoItem.di
 Where NumeroOrcamento = 89.

 Bom, eu preciso pegar o nome do cliente que esta em outra tabela, pegar a
 descrição da condição que também esta em outra tabela e fora o código e
 descrição do produto que também estão em outra tabela. Pra tudo isto eu uso
 SubSQL, atravez de funções. Na pratica fica assim:


 Select  *,
     Func_RetornaNomeCliente(IdClientOrcamento) as NomeCliente,
     Func_RetornaDescricaoCondicao(IdCondOrcamento) as
 DescricaoCondicao
 From Orcamento left join OrcamentoItem on Orcamento.id =
 OrcamentoItem.di
 Where NumeroOrcamento = 89.

 Bom, as funções tu já sabe criar, não é???


 Marcos André G.A
 Trabin Softwarre  Consulting



 Em 17 de maio de 2010 10:20, vinicius perroni vinicius...@gmail.com
 escreveu:

 Bom dia a todos.

 Estou com um velho problema uma consulta minha utiliza muitos LEFT
 JOINS tornandoa lenta demais.

 A consulta é mais ou menos assim tenho uma tabela de orçamentos, uma
 de ordens de compras e outra de Notas Fiscas, três tabelas sendo o
 unico registro que certamente existe é o orçamento. Junto elas com
 LEFT JOIN ...

 Pensei em usar UNION mas ainda não realizei testes alguem tem alguma
 ideia para substituir os LEFT JOINS e otimizar a consulta?


 Att
 Vinicius Perroni
 ___
 pgbr-geral mailing list
 pgbr-geral@listas.postgresql.org.br
 https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral


 ___
 pgbr-geral mailing list
 pgbr-geral@listas.postgresql.org.br
 https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral





-- 
Vinicius Perroni
___
pgbr-geral mailing list
pgbr-geral@listas.postgresql.org.br
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral


Re: [pgbr-geral] Otimizar consulta com LEFT JOIN

2010-05-17 Por tôpico Mozart Hasse
Olá Vinicius,

 From: vinicius perroni vinicius...@gmail.com
 Subject: [pgbr-geral] Otimizar consulta com LEFT JOIN

 Estou com um velho problema uma consulta minha utiliza muitos LEFT
 JOINS tornandoa lenta demais.
 
 A consulta é mais ou menos assim tenho uma tabela de orçamentos, uma
 de ordens de compras e outra de Notas Fiscas, três tabelas sendo o
 unico registro que certamente existe é o orçamento. Junto elas com
 LEFT JOIN ...
 
 Pensei em usar UNION mas ainda não realizei testes alguem tem alguma
 ideia para substituir os LEFT JOINS e otimizar a consulta?

Aplique a idéia de usar UNION ALL. Isso funciona em qualquer servidor SQL e
nunca vi piorar o desempenho da consulta. O que faço é o seguinte: para CADA
LEF OUTER JOIN da sua consulta, substitua por duas cópias da mesma query
separadas por UNION ALL (não union, tem de ser UNION ALL), sendo que numa
delas você vai trocar o LEFT OUTER JOIN por um INNER JOIN e na outra você
vai tirar fora o LEFT OUTER da tabela e incluir lá na cláusula WHERE a
condição AND NOT EXISTS(SELECT 1 FROM suatabeladoleft WHERE joins que
estavam no LEFT). Provavelmente você vai notar que ao por INNER na tabela
que antes era OUTER você poderá trocar um monte de OUTERs por INNERs nas
tabelas filhas dela também, o que ajudará ainda mais a melhorar o
desempenho.

A implicação disso é que, se tua query tem 2 LEFT OUTER, a combinação de
todos com todos vai resultar em 4 consultas separadas por UNION ALL. Nunca
precisei de mais do que 8. Não se assuste porque valerá a pena.
Sua query vai ficar grande, porém mesmo seis vezes maior ainda ficará muito
mais rápida que a original. Faço isso aqui direto com ótimos resultados.
Minha aplicação não sofreu nenhuma alteração na modelagem por conta
disso, porém com essas trocas para UNION ALL, o LEFT OUTER JOIN está virando
lenda por aqui, praticamente ninguém mais usa.

Atenciosamente,

Mozart Hasse


___
pgbr-geral mailing list
pgbr-geral@listas.postgresql.org.br
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral