- Existe a percepção de que a Full-Text Search (FTS) nativa do PostgreSQL é lenta, mas, com a otimização adequada, ela pode ser muito rápida
- No blog da Neon, foi feita uma comparação entre a extensão
pg_search, baseada em Rust, e a FTS nativa, defendendo que a segunda seria lenta
- Porém, é muito provável que essa comparação tenha sido feita sem otimizações básicas indispensáveis para a FTS do PostgreSQL
- Este artigo demonstra com números que, aplicando apenas otimizações simples à configuração padrão da FTS, é possível obter um ganho de desempenho de 50x
Visão geral da configuração do benchmark
- O teste foi realizado com base em uma tabela com 10 milhões de registros de log
CREATE TABLE benchmark_logs (
id SERIAL PRIMARY KEY,
message TEXT,
country VARCHAR(255),
severity INTEGER,
timestamp TIMESTAMP,
metadata JSONB
);
- Estrutura da consulta problemática:
SELECT country, COUNT(*)
FROM benchmark_logs
WHERE to_tsvector('english', message) @@ to_tsquery('english', 'research')
GROUP BY country
ORDER BY country;
- Executar
to_tsvector() dentro da consulta → muito ineficiente
- Mesmo com índice GIN, ele não é aproveitado corretamente
Ambiente de teste (reprodução da configuração base)
Fator 1 de perda de desempenho: cálculo de tsvector em tempo real
Fator 2 de perda de desempenho: configuração fastupdate=on no índice GIN
Ganho de desempenho: melhoria de mais de 50x
- Antes da otimização: cerca de 41,3 segundos (41.301 ms)
- Depois da otimização: cerca de 0,88 segundo (877 ms)
- Isso representa um ganho de desempenho de aproximadamente 50x
- Esse resultado foi obtido mesmo em um ambiente com pouco paralelismo
O desempenho de ts_rank pode realmente ser lento
ts_rank ou ts_rank_cd podem ser relativamente lentos, pois avaliam todos os resultados antes de ordenar
- Especialmente com grandes volumes de resultados, a carga de CPU/IO pode ser alta
Recurso avançado de ranking: extensão VectorChord-BM25
- Quando precisão de ordenação e velocidade são importantes, usar uma extensão dedicada pode ser mais eficaz
- VectorChord-BM25 é uma extensão para PostgreSQL que oferece ranking baseado no algoritmo BM25
- Há relatos de que ela pode ser 3x mais rápida que o Elasticsearch
Vantagens do VectorChord-BM25
- Algoritmo BM25: algoritmo de ranking de busca mais avançado que TF-IDF
- Formato de índice dedicado: otimizado para buscas de alta velocidade, como Block WeakAnd
- Fornece o tipo
bm25vector: armazena representações tokenizadas
- Melhora tanto a precisão quanto a velocidade da busca
Conclusão: a FTS nativa do PostgreSQL também é rápida o suficiente
- Com uma coluna
tsvector e um índice GIN adequado (fastupdate=off), é possível ter buscas muito rápidas mesmo com a FTS nativa
- Comparações de desempenho devem ser feitas com uma base devidamente otimizada
- Se for necessário um recurso de ranking mais avançado, vale considerar extensões como VectorChord-BM25
- Mensagem principal: o problema pode não ser a ferramenta ser lenta, mas sim a configuração
3 comentários
Graças a isso, fiz o tuning da consulta.
Os comentários no Hacker News dão medo... "Dez milhões? Tá de brincadeira?"
Comentários do Hacker News
Como mantenedor do
pg_search, segundo a documentação do Postgres, tanto o artigo da Neon/ParadeDB quanto a estratégia usada aqui são apresentados como alternativas válidaspg_searchfoi projetado para resolver este segundo problema, e os benchmarks também refletem issopg_searchfunciona com vários tipos de consulta no "estilo Elastic" e tipos do Postgres apenas com uma definição simples de índiceCalcular
tsvectorem tempo real é um grande erroNão consigo entender a tendência de querer colocar tudo dentro do Postgres
Fico feliz em ver mais implementações de busca full-text nativas do Postgres
lucene/tantivy) foram projetadas para segmentos imutáveis e, quando combinadas com tabelas heap do Postgres, podem resultar em uma solução piorSem o plano de execução, é difícil entender o que está acontecendo
tsvectorem tempo real se aplica apenas aos itens correspondentes, e como a consulta do benchmark usaLIMIT 10, há pouca rechecagemHá alguns anos, eu queria usar FTS nativo, mas fracassei
Empacotei extensões RPM/DEB para
pg_searchevchord_bm25Já vi muitas equipes irem direto para Elasticsearch ou Meilisearch
10 milhões de registros é um dataset de brinquedo
Usei full text do pg pela primeira vez por volta de 2008