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.1 >> Tabela 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.word >> WHERE >> 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 > Pedro criei as duas tabelas aqui e veja a diferença no explain SELECT p.id, p.name FROM 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 p WHERE 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
