Re: [pgbr-geral] Otimizar consulta com LEFT JOIN
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
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
- 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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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