- Existe la percepción de que el Full-Text Search (FTS) nativo de PostgreSQL es lento, pero con la optimización adecuada puede funcionar muy rápido
- En el blog de Neon se compara la extensión
pg_search, basada en Rust, con el FTS nativo, y se afirma que este último es lento
- Sin embargo, es muy probable que esa comparación se haya hecho omitiendo optimizaciones básicas indispensables para el FTS de PostgreSQL
- Este artículo demuestra con cifras que incluso aplicando optimizaciones simples a la configuración base del FTS se puede lograr una mejora de 50 veces en el rendimiento
Resumen de la configuración del benchmark
- Se realizó una prueba basada en una tabla con 10 millones de registros de logs
CREATE TABLE benchmark_logs (
id SERIAL PRIMARY KEY,
message TEXT,
country VARCHAR(255),
severity INTEGER,
timestamp TIMESTAMP,
metadata JSONB
);
- Estructura de la consulta problemática:
SELECT country, COUNT(*)
FROM benchmark_logs
WHERE to_tsvector('english', message) @@ to_tsquery('english', 'research')
GROUP BY country
ORDER BY country;
- Ejecutar
to_tsvector() dentro de la consulta → muy ineficiente
- Incluso si hay un índice GIN, no se aprovecha correctamente
Entorno de pruebas (réplica de la configuración base)
Factor 1 de degradación: cálculo de tsvector en tiempo real
Factor 2 de degradación: fastupdate=on en el índice GIN
Mejora de rendimiento: más de 50 veces
- Antes de optimizar: aprox. 41.3 segundos (41,301 ms)
- Después de optimizar: aprox. 0.88 segundos (877 ms)
- Muestra una mejora de rendimiento de alrededor de 50 veces
- Es posible alcanzar este rendimiento incluso en entornos con poco paralelismo
El rendimiento de ts_rank sí puede ser realmente lento
ts_rank o ts_rank_cd pueden ser relativamente lentos porque evalúan todos los resultados antes de ordenarlos
- Especialmente al manejar grandes volúmenes de resultados, la carga de CPU/IO es alta
Funciones avanzadas de ranking: extensión VectorChord-BM25
- Si la precisión y la velocidad del ordenamiento son importantes, puede ser más efectivo usar una extensión dedicada
- VectorChord-BM25 es una extensión para PostgreSQL que ofrece funciones de ranking basadas en el algoritmo BM25
- Incluso hay reportes de que es 3 veces más rápido que Elasticsearch
Ventajas de VectorChord-BM25
- Algoritmo BM25: un algoritmo de ranking de búsqueda más avanzado que TF-IDF
- Formato de índice dedicado: optimizado para búsquedas de alta velocidad como Block WeakAnd
- Proporciona el tipo
bm25vector: almacena representaciones tokenizadas
- Mejora tanto la precisión como la velocidad de búsqueda
Conclusión: el FTS nativo de PostgreSQL también es suficientemente rápido
- Si se usan una columna
tsvector y un índice GIN adecuado (fastupdate=off), es posible lograr búsquedas muy rápidas incluso con el FTS nativo
- Las comparaciones de rendimiento deben hacerse sobre una base optimizada
- Si se necesitan funciones avanzadas de ranking, vale la pena considerar herramientas de extensión como VectorChord-BM25
- Mensaje clave: no es que la herramienta sea lenta, sino que la configuración puede ser el problema
3 comentarios
Gracias a eso, optimizamos la consulta.
Las opiniones en Hacker News dan miedo... "¿Diez millones? ¿Es una broma?"
Comentarios en Hacker News
Como mantenedor de pg_search, según la documentación de Postgres, tanto la estrategia del artículo de Neon/ParadeDB como la usada aquí se presentan como alternativas válidas
Calcular
tsvectoren tiempo real es un gran errorNo entiendo la tendencia de querer meter todo en Postgres
Me alegra ver más implementaciones de búsqueda de texto completo nativas de Postgres
Sin el plan de ejecución es difícil entender qué está pasando
tsvectorsolo se aplica a las coincidencias, y como la consulta del benchmark usaLIMIT 10, hay poca reverificaciónHace algunos años quise usar FTS nativo, pero fracasé
Empaqueté extensiones RPM/DEB para pg_search y vchord_bm25
He visto a muchos equipos saltar directamente a Elasticsearch o Meilisearch
10 millones de registros es un dataset de juguete
Usé por primera vez el texto completo de pg alrededor de 2008