[pgbr-geral] Ajuda com view.
Boa tarde pessoal, Tenho uma view criada assim: CREATE VIEW visao AS SELECT chave AS produto, produto FROM produtos; Então eu faço um select assim: SELECT chave, produto FROM visao WHERE produto = 1234; até aqui legal. Porém quando faço: SELECT chave, produto FROM visao WHERE produto IN ( SELECT codigo FROM produtos_contados ), o plano de execução muda radicalmente neste segundo caso, no segundo caso ele está fazendo um seq scan completo na tabela de produtos, mesmo que na tabela produtos_contados do exemplo tenha apenas um produto, por exemplo, o 1234; Nossas estatísticas estão atualizadas, já tentei mudar a consulta de várias formas, mas preciso utilizar o operador IN. Alguém tem alguma sugestão, do que eu poderia olhar? Versão 8.4.12. ___ pgbr-geral mailing list pgbr-geral@listas.postgresql.org.br https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral
Re: [pgbr-geral] Ajuda com view.
até aqui legal. Porém quando faço: SELECT chave, produto FROM visao WHERE produto IN ( SELECT codigo FROM produtos_contados ), o plano de execução muda radicalmente neste segundo caso, no segundo caso Com IN esse comportamento é bem comum. O IN é bom para um conjunto limitado de valores. Por exemplo, produto in (10, 20, 40, 50). Fazer IN para juntar tabelas não é a melhor opção. Tente fazer um join, mais ou menos assim: SELECT v.chave, v.produto FROM visao v join produtos_contados pc on v.produto = pc.codigo; Creio que você terá resultados mais performáticos desta forma. -- Marcone Peres - DBA http://www.linkedin.com/in/marconeperes @marconeperes (61) 8146-0028 ___ pgbr-geral mailing list pgbr-geral@listas.postgresql.org.br https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral
Re: [pgbr-geral] Ajuda com view.
Em 25 de julho de 2012 14:38, Vinicius Santos vinicius.santos.li...@gmail.com escreveu: Nossas estatísticas estão atualizadas, já tentei mudar a consulta de várias formas, mas preciso utilizar o operador IN. Por que precisa utilizar o IN? De acordo com o número de registros o PostgreSQL é inteligente o suficiente para escolher entre um índice ou outro, ou então um seq scan, principalmente quando o índice não interfere em nada - no caso, com 1 registro na tabela. Como sugestão, você pode trocar o seu IN por EXISTS fazendo apenas uma pequena modificação: SELECT chave, produto FROM visao WHERE EXISTS ( SELECT 1 FROM produtos_contados WHERE visao.produto = produtos_contados.codigo ) Assim obterá mais desempenho, mas para observar mudança no plano de acesso terás que popular sua tabela com mais registros. -- TIAGO J. ADAMI http://www.adamiworks.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] Ajuda com view.
Com IN esse comportamento é bem comum. O IN é bom para um conjunto limitado de valores. Por exemplo, produto in (10, 20, 40, 50). Fazer IN para juntar tabelas não é a melhor opção. Tente fazer um join, mais ou menos assim: Estou utilizando o IN com um conjunto bem limitado de valores. Nos meus testes estou usando apenas um registro dentro do IN. Seu passar o valor explicitamente o PostgreSQL utiliza um plano, se eu passar o mesmo valor, mas através de um SELECT dentro do IN, então o PostgreSQL utiliza outro plano. ___ pgbr-geral mailing list pgbr-geral@listas.postgresql.org.br https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral
Re: [pgbr-geral] Ajuda com view.
2012/7/25 Vinicius Santos vinicius.santos.li...@gmail.com Com IN esse comportamento é bem comum. O IN é bom para um conjunto limitado de valores. Por exemplo, produto in (10, 20, 40, 50). Fazer IN para juntar tabelas não é a melhor opção. Tente fazer um join, mais ou menos assim: Estou utilizando o IN com um conjunto bem limitado de valores. Nos meus testes estou usando apenas um registro dentro do IN. Seu passar o valor explicitamente o PostgreSQL utiliza um plano, se eu passar o mesmo valor, mas através de um SELECT dentro do IN, então o PostgreSQL utiliza outro plano. Cara, cuidado! Seq scan não é sinônimo de lentidão. Como o Tiago disse, caso a tabela produtos não seja muito grande (e.g. algumas páginas) é natural que o PostgreSQL escolha um seq scan ao invés de um index scan, já que o index scan poderia acarretar mais leituras em disco que um simples seq scan. Uma forma simples de saber se a tabela é grande ou não para um index scan é a consulta abaixo: SELECT relpages FROM pg_class WHERE relname = 'produtos'; Ela te traz a quantidade de páginas usadas para armazenar os dados da tabela. Não é esse o seu caso? A consulta está realmente mais lenta (se comparada à anterior)? No PostgreSQL 9.2 com o index-only scan, pode ser que o seq scan seja menos usado, inclusive nesses casos. Atenciosamente, -- Matheus de Oliveira ___ pgbr-geral mailing list pgbr-geral@listas.postgresql.org.br https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral
Re: [pgbr-geral] Ajuda com view.
Cara, cuidado! Seq scan não é sinônimo de lentidão. Como o Tiago disse, caso a tabela produtos não seja muito grande (e.g. algumas páginas) é natural que o PostgreSQL escolha um seq scan ao invés de um index scan, já que o index scan poderia acarretar mais leituras em disco que um simples seq scan. Certo. O que quis dizer é que o select está literamente passando todos os registros da tabela de produto. Eu comprovei isto assim: SELECT chave, produto, funcao_teste( chave ) FROM visao WHERE produto IN ( SELECT codigo FROM produtos_contados ) Dentro da funcao_teste eu dou um RAISE NOTICE, com o código do produto, passado por parâmetro na função. Eu pude verificar que o select dessa maneira, com IN, está passando em todos os produtos cadastrados. Se eu fizer sem o IN, passando os valores literais, apenas os registros corretos são lidos, também pude comprovar isto com a saída da funcao_teste. O que me intriga, é que atualizamos a versão do kernel rescentemente, da 2.6 para 3.2, e ao mesmo tempo atualizamos o PostgreSQl do 8.4.8 para 8.4.12. Teoricamente, a atualização não tem nada a ver. Certo? ___ pgbr-geral mailing list pgbr-geral@listas.postgresql.org.br https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral
Re: [pgbr-geral] Ajuda com view.
Vinicius == Vinicius Santos vinicius.santos.li...@gmail.com writes: Vinicius Certo. O que quis dizer é que o select está literamente passando Vinicius todos os registros da tabela de produto. Eu comprovei isto assim: Vinicius SELECT chave, produto, funcao_teste( chave ) FROM visao WHERE produto Vinicius IN ( SELECT codigo FROM produtos_contados ) Vinicius Dentro da funcao_teste eu dou um RAISE NOTICE, com o código do Vinicius produto, passado por parâmetro na função. Vinicius Eu pude verificar que o select dessa maneira, com IN, está passando Vinicius em todos os produtos cadastrados. Vinicius Se eu fizer sem o IN, passando os valores literais, apenas os Vinicius registros corretos são lidos, também pude comprovar isto com a saída Vinicius da funcao_teste. É um seq scan porque é muito difícil correlacionar os critérios do subselect genericamente com o where da tabela à esquerda e não tem como prever quantos valores esse subselect vai retornar, assim o planner não tem como avaliar o melhor plano antes da query começar a executar, e por isso esse caso sempre vai ser um seq scan. Usando um join com um critério explícito, o planner sabe qual índice usar antes da query rodar e elabora um plano mais eficiente (presumindo que existam índices adequados): SELECT v.chave, v.produto FROM visao v JOIN produtos_contados pc ON v.produto = pc.codigo; O mesmo vale quando você usa valores literais no where, com um valor constante no critério, o planner consegue olhar no índice e saber se a quantidade de registros que passam no critério pedem um seq scan ou não. Vinicius O que me intriga, é que atualizamos a versão do kernel rescentemente, Vinicius da 2.6 para 3.2, e ao mesmo tempo atualizamos o PostgreSQl do 8.4.8 Vinicius para 8.4.12. Vinicius Teoricamente, a atualização não tem nada a ver. Certo? Não, não tem nada a ver. -- Eden Cardim +55 11 9644 8225 ___ pgbr-geral mailing list pgbr-geral@listas.postgresql.org.br https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral
[pgbr-geral] Ajuda com VIEW
Olá... Estou tentando fazer uma VIEW que seja equivalente a: select rowid from rfc.trivias where rowid not in (select idtrivia from rfc.triviavotos where idclien = 8382); só que gostaria de deixar o idclien variável né, não fixo. Passei isso para uma pessoa que cuida do banco de dados e ela fez a seguinte view: SELECT t.rowid, t.created, t.updated, t.idcriador, t.pergunta, t.resp1, t.resp2, t.resp3, t.resp4, t.respcerta, t.linkfoto, t.idfilmescorr, t.atorescorr, t.status, aa.idclien FROM rfc.trivias t, ( SELECT triviavotos.idtrivia, triviavotos.idclien FROM rfc.triviavotos) aa WHERE t.rowid aa.idtrivia; Assim, segundo ele, teoricamente era só passar um WHERE idclien = 8382 na view e meus problemas estariam resolvidos, mas isso não aconteceu.. Acabaram vindo múltiplos resultados iguais... O problema é que, com a minha view, não consigo passar o WHERE idclien = 8382, pois ele está na subquery.. Alguma idéia do que fazer?? Grato, Wagner Bonfiglio ___ pgbr-geral mailing list pgbr-geral@listas.postgresql.org.br https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral
Re: [pgbr-geral] Ajuda com VIEW
2008/7/10 Wagner Bonfiglio [EMAIL PROTECTED]: Estou tentando fazer uma VIEW que seja equivalente a: select rowid from rfc.trivias where rowid not in (select idtrivia from rfc.triviavotos where idclien = 8382); só que gostaria de deixar o idclien variável né, não fixo. Tire o WHERE, e use-o ao consultar a visão... SELECT rowid FROM visão WHERE idclien = 8382 ; -- skype:leandro.gfc.dutra?chat Yahoo!: ymsgr:sendIM?lgcdutra +55 (11) 3040 7300 r155 gTalk: xmpp:[EMAIL PROTECTED] +55 (11) 9406 7191 ICQ/AIM: aim:GoIM?screenname=61287803 +55 (11) 5685 2219 MSN: msnim:[EMAIL PROTECTED] ___ pgbr-geral mailing list pgbr-geral@listas.postgresql.org.br https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral
Re: [pgbr-geral] Ajuda com VIEW
Leando, o problema é que o IDCLIEN está na tabela triviavotos, que aparece somenta na subquery. Acedito que tenha sido por isso que a outra pessoa tenha jogado a subquery como se fosse uma tabela... Apenas explicando um pouco melhor.. Eu tenho uma tabela de trivias... Eu tenho uma tabela que indica as trivias que cada usuario votou... O que eu desejo é pegar apenas as trivias que o usuário não votou Aquela consulta funciona beleza, mas não consegui jogar ela pra uma VIEW. On Thu, Jul 10, 2008 at 2:43 PM, Leandro DUTRA [EMAIL PROTECTED] wrote: 2008/7/10 Wagner Bonfiglio [EMAIL PROTECTED]: Estou tentando fazer uma VIEW que seja equivalente a: select rowid from rfc.trivias where rowid not in (select idtrivia from rfc.triviavotos where idclien = 8382); só que gostaria de deixar o idclien variável né, não fixo. Tire o WHERE, e use-o ao consultar a visão... SELECT rowid FROM visão WHERE idclien = 8382 ; -- skype:leandro.gfc.dutra?chat Yahoo!: ymsgr:sendIM?lgcdutra +55 (11) 3040 7300 r155 gTalk: xmpp:[EMAIL PROTECTED] +55 (11) 9406 7191 ICQ/AIM: aim:GoIM?screenname=61287803 +55 (11) 5685 2219 MSN: msnim:[EMAIL PROTECTED] ___ 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] Ajuda com VIEW
Wagner Bonfiglio escreveu: Olá... Estou tentando fazer uma VIEW que seja equivalente a: select rowid from rfc.trivias where rowid not in (select idtrivia from rfc.triviavotos where idclien = 8382); só que gostaria de deixar o idclien variável né, não fixo. Passei isso para uma pessoa que cuida do banco de dados e ela fez a seguinte view: SELECT t.rowid, t.created, t.updated, t.idcriador, t.pergunta, t.resp1, t.resp2, t.resp3, t.resp4, t.respcerta, t.linkfoto, t.idfilmescorr, t.atorescorr, t.status, aa.idclien FROM rfc.trivias t, ( SELECT triviavotos.idtrivia, triviavotos.idclien FROM rfc.triviavotos) aa WHERE t.rowid aa.idtrivia; Assim, segundo ele, teoricamente era só passar um WHERE idclien = 8382 na view e meus problemas estariam resolvidos, mas isso não aconteceu.. Acabaram vindo múltiplos resultados iguais... O problema é que, com a minha view, não consigo passar o WHERE idclien = 8382, pois ele está na subquery.. Alguma idéia do que fazer?? Verifique se prepared statements ajuda: http://www.postgresql.org/docs/current/interactive/sql-prepare.html http://www.postgresql.org/docs/current/interactive/sql-execute.html http://www.postgresql.org/docs/current/interactive/sql-deallocate.html Osvaldo ___ pgbr-geral mailing list pgbr-geral@listas.postgresql.org.br https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral
Re: [pgbr-geral] Ajuda com VIEW
Vou dar uma estudada nisso... Valeu! 2008/7/10 Osvaldo Rosario Kussama [EMAIL PROTECTED]: Wagner Bonfiglio escreveu: Olá... Estou tentando fazer uma VIEW que seja equivalente a: select rowid from rfc.trivias where rowid not in (select idtrivia from rfc.triviavotos where idclien = 8382); só que gostaria de deixar o idclien variável né, não fixo. Passei isso para uma pessoa que cuida do banco de dados e ela fez a seguinte view: SELECT t.rowid, t.created, t.updated, t.idcriador, t.pergunta, t.resp1, t.resp2, t.resp3, t.resp4, t.respcerta, t.linkfoto, t.idfilmescorr, t.atorescorr, t.status, aa.idclien FROM rfc.trivias t, ( SELECT triviavotos.idtrivia, triviavotos.idclien FROM rfc.triviavotos) aa WHERE t.rowid aa.idtrivia; Assim, segundo ele, teoricamente era só passar um WHERE idclien = 8382 na view e meus problemas estariam resolvidos, mas isso não aconteceu.. Acabaram vindo múltiplos resultados iguais... O problema é que, com a minha view, não consigo passar o WHERE idclien = 8382, pois ele está na subquery.. Alguma idéia do que fazer?? Verifique se prepared statements ajuda: http://www.postgresql.org/docs/current/interactive/sql-prepare.html http://www.postgresql.org/docs/current/interactive/sql-execute.html http://www.postgresql.org/docs/current/interactive/sql-deallocate.html Osvaldo ___ 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