Mejores prácticas de búsqueda de texto completo
Cómo usar esta lista
- Aplícala antes de lanzar la búsqueda orientada al usuario en producción.
- Vuelve a ejecutarla después de importaciones masivas de contenido o cambios en el diccionario.
- Combínala con la lista de verificación de búsqueda híbrida si pgvector está habilitado.
A - Esquema y Vectores
- Almacena
tsvectoren una columna, no usesto_tsvector()en tiempo de ejecución en WHERE. Generado, ALMACENADO o mantenido por disparador (trigger). - Da más peso al título que al cuerpo.
setweightA para el título, B para el cuerpo, C para las etiquetas. - Elige la configuración por tipo de contenido.
englishpara prosa;simplepara SKUs y códigos de error. - Mantén el contenido y el vector sincronizados. Una sola transacción actualiza el texto y cualquier campo derivado.
- Añade columnas de tenant o ACL antes de los índices. Filtra temprano en consultas híbridas y FTS.
B - Índices
- Por defecto usa GIN en
tsvector. Usa GiST solo después de que un benchmark intensivo en escrituras demuestre beneficio. - Crea con
CREATE INDEX CONCURRENTLYen tablas grandes. Evita bloqueos de escritura en producción. - Reindexa después de importaciones masivas.
REINDEX INDEX CONCURRENTLYo reconstruye durante una ventana de mantenimiento. - Ejecuta
ANALYZEdespués de reindexar. El planificador necesita estadísticas actualizadas para los escaneos de mapa de bits (bitmap scans). - Índices parciales para filas publicadas solamente. Reduce el tamaño del índice cuando hay muchos borradores.
C - Consultas y UX
- Nunca concatenes la entrada del usuario en cadenas
tsquery. Usaplainto_tsqueryowebsearch_to_tsquery. - Limita el fanout de OR. Requiere un
ts_rankmínimo o limita los términos OR de los analizadores de usuario. - Proporciona fragmentos con
ts_headline. Mejora la experiencia del usuario de los resultados sin análisis del lado de la aplicación. - Ordena por rango y luego por fecha de publicación.
ORDER BY rank DESC, published_at DESCrompe empates de forma sensata. - Registra consultas sin resultados. Alimenta el diccionario de sinónimos y el análisis de brechas de contenido.
D - Operaciones
- Monitoriza el tamaño del índice GIN y
idx_scan. Unidx_scanplano con consultas lentas significa que faltaANALYZEo una configuración incorrecta. - Ajusta
autovacuumen tablas de búsqueda con mucha rotación. Las actualizaciones de texto regeneran vectores y páginas GIN. - Documenta los cambios en el diccionario y los sinónimos. Requiere reindexar o reconstruir vectores en algunos casos.
- Realiza benchmarks antes de Elasticsearch. Demuestra que FTS de Postgres no cumple los SLO con concurrencia realista.
- Prueba las políticas de RLS con el rol de la API de búsqueda. FTS hereda las políticas de tabla; verifica el aislamiento del tenant.
Preguntas Frecuentes
¿Cuándo reindexar?
Después de una importación masiva con COPY, una actualización de versión principal o cambios en archivos de diccionario que afecten la derivación (stemming).¿`fastupdate` activado o desactivado?
Activado para un flujo constante de inserciones; considera desactivarlo durante cargas masivas y luego reindexar.¿Pesos de búsqueda híbrida?
Documenta los pesos iniciales; evalúa recall@10 trimestralmente con consultas de referencia (golden queries).¿Multilenguaje?
Separa `tsvector` por idioma o usa `simple` más modelos de incrustación específicos del idioma.¿Necesidades de subcadena?
Añade un índice `pg_trgm` junto a GIN; expón diferentes modos de búsqueda en la API.¿Volumen de datos en staging?
Usa un tamaño de corpus representativo; staging vacío oculta errores de escaneo secuencial (seq scan).¿Poolers de conexión?
El modo de transacción de pgbouncer está bien; la búsqueda es una carga de trabajo SELECT intensiva en lectura.¿Réplicas de lectura?
Dirige las lecturas de búsqueda a las réplicas; acepta latencia de replicación para índices casi en tiempo real.¿Escape hatch a OpenSearch?
Documenta los criterios de ADR antes de la adopción; la escritura dual es costosa.¿Comprobaciones en CI?
El lint de migraciones asegura que la columna generada y el índice GIN se creen juntos.Relacionado
- Conceptos básicos de búsqueda de texto completo - ADR de FTS vs Elasticsearch
- Índices GIN para FTS - creación y mantenimiento
- tsvector y tsquery - ranking y diccionarios
- Búsqueda Híbrida - combinación con pgvector
- Mejores prácticas de diseño de índices - higiene general de índices
Versiones de la pila: Esta página fue escrita para PostgreSQL 18.4 (estable 18, mantenimiento 17), pgvector 0.8+, PostGIS 3.5+, pgbouncer 1.x, y Patroni 3.x.