massa, uma funcionalidade nova do postgres 9.3 que resolveria esse problema ( em partes ), seria o uso de uma view materializada, onde durante a madrugada faria um refresh ...
:D Date: Thu, 5 Dec 2013 17:13:46 -0200 From: [email protected] To: [email protected] Subject: Re: [pgbr-geral] Select com blacklist (como melhorar a performance) eaí! =) sim, eu já tinha uma insert trigger fazendo algumas rotinas, então apenas acrescentei este campo. ta funcionando perfeitamente! abraço! Em 5 de dezembro de 2013 17:04, Diego Lenhardt <[email protected]> escreveu: opa legal a idéia, mas e quando surgirem novos produtos? terá que sempre rodar esse update? vai por em trigger? falows Date: Thu, 28 Nov 2013 18:17:50 -0200 From: [email protected] To: [email protected] Subject: Re: [pgbr-geral] Select com blacklist (como melhorar a performance) CONSEGUI!! caramba, passei o dia todo nisso, mas finalmente consegui uma alternativa viável (14s pra cruzar 200.000 x 400) Agradeço a quem tentou ajudar! E aproveitando para responder: EXISTS tinha um tempo de execução semelhante, e IN não era possível, pois eu precisava buscar pela palavra inteira em qualquer lugar da string do nome do produto. Segue minha solução: utilizei query de Full Text Search (@@) aliado a um dicionário 'dummy'. ALTER TEXT SEARCH DICTIONARY simple(dummy);ALTER TEXT SEARCH CONFIGURATION portuguese ALTER MAPPING FOR asciiword WITH simple; com isso, a normalização do to_tsvector() e plainto_tsquery() ficam 'literais'. na tabela products, criei uma coluna com indice 'tsvector_name' (tsvector), rodando após a seguinte query: UPDATE productsSET tsvector_name = to_tsvector(NAME) e na tabela bad_words, fiz o mesmo, criando a coluna com indice 'tsquery_word' (tsquery) e rodando: UPDATE bad_wordsSET tsquery_word = plainto_tsquery('simple', word); no final das contas, a query de busca final ficou: SELECT p.id, p.name, bw.* FROM products p LEFT JOIN bad_words bw ON p.tsvector_name @@ bw.tsquery_word WHERE bw.id IS NULL e tá resolvido! =) Em 28 de novembro de 2013 15:52, Douglas Fabiano Specht <[email protected]> escreveu: Em 28 de novembro de 2013 15:24, Douglas Fabiano Specht <[email protected]> escreveu: Em 28 de novembro de 2013 14:00, Pedro Cavalheiro <[email protected]> escreveu: Boa tarde! Estou com um problema de performance em uma query, talvez alguém possa me ajudar! Situação: Postgres 9.1Tabela produtos (id, nome) Tabela bad_words (id, word) Preciso basicamente selecionar todos os registros de products, removendo os produtos cujo nome possui alguma palavra listada na tabela bad_words. Uma query para realizar isso, não é complexa... Daria pra fazer assim: SELECT p.id, p.name FROM products p LEFT JOIN bad_words bw ON p.name ~* bw.wordWHERE bw.id IS NULL Acredito que meu problema seja no número de cruzamentos realizados. Minha tabela de produtos, atualmente está com 200.000 registros, e a previsão é aumentar até 7.000.000 nos próximos meses. A tabela bad_words atualmente possui em torno de 400 registros. Rodando a consulta acima, o processamento leva em torno de 20 minutos (Intel i5 2.9ghz, 8gb ram, hd 7200rpm), inviável para a aplicação... Sei que milagres não existem, mas acredito que haja algum modo de indexar os valores envolvidos nesta consulta, ou melhorar a query, com a finalidade de diminuir o tempo total. Alguém tem alguma ideia? Agradeço pela ajuda! _______________________________________________ pgbr-geral mailing list [email protected] https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral ola..amigo, poderia postar um explain e a ddl das tabelas?tentou utilizar um in ou exists? -- Douglas Fabiano Specht Pedrocriei as duas tabelas aqui e veja a diferença no explain SELECT p.id, p.nameFROM products p LEFT JOIN bad_words bw ON p.name ~*bw.word WHERE bw.id IS NULL explain: "Nested Loop Left Join (cost=0.00..72167266.22 rows=1 width=37)"" Join Filter: ((p.name)::text ~* (bw.word)::text)" " Filter: (bw.id IS NULL)"" -> Seq Scan on products p (cost=0.00..4496.25 rows=245225 width=37)" " -> Materialize (cost=0.00..458.27 rows=19618 width=37)" " -> Seq Scan on bad_words bw (cost=0.00..360.18 rows=19618 width=37)" mudei o select para um in(nao sei se essa a sua ideia) SELECT p.id, p.name FROM products pWHERE p.name in(select word from bad_words where id IS NUL) explain: "Hash Semi Join (cost=605.40..10006.16 rows=245225 width=37)" " Hash Cond: ((p.name)::text = (bad_words.word)::text)"" -> Seq Scan on products p (cost=0.00..4496.25 rows=245225 width=37)" " -> Hash (cost=360.18..360.18 rows=19618 width=33)"" -> Seq Scan on bad_words (cost=0.00..360.18 rows=19618 width=33)" Veja que a opção 2 o custo é bem menor, veja se nao pode utilizar ela.. -- Douglas Fabiano Specht _______________________________________________ pgbr-geral mailing list [email protected] https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral _______________________________________________ pgbr-geral mailing list [email protected] https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral _______________________________________________ pgbr-geral mailing list [email protected] https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral _______________________________________________ pgbr-geral mailing list [email protected] https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral
_______________________________________________ pgbr-geral mailing list [email protected] https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral
