[pgbr-geral] Ajuda com view.

2012-07-25 Por tôpico Vinicius Santos
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.

2012-07-25 Por tôpico Marcone
 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.

2012-07-25 Por tôpico Tiago Adami
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.

2012-07-25 Por tôpico Vinicius Santos


 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-07-25 Por tôpico Matheus de Oliveira
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.

2012-07-25 Por tôpico Vinicius Santos
 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.

2012-07-25 Por tôpico Eden Cardim
 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

2008-07-10 Por tôpico Wagner Bonfiglio
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-07-10 Por tôpico Leandro DUTRA
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

2008-07-10 Por tôpico Wagner Bonfiglio
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

2008-07-10 Por tôpico Osvaldo Rosario Kussama
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

2008-07-10 Por tôpico Wagner Bonfiglio
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