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

Responder a