PostgreSQL: Full-Text Search: Performance
Module: Database-Specific Features
Full-Text Search performance depends on GIN indexes and query complexity: (1) GIN indexes: Essential for performance (100x faster), index tsvector columns or generated columns. (2) Generated columns: Better than expression indexes (pre-computed, faster queries). (3) Query complexity: Simple queries (single word) fast, complex queries (multiple operators) slower. (4) Document size: Large documents (> 1MB) slow down indexing and search. (5) Index size: GIN indexes are large (30-50% of table size), plan storage accordingly. (6) Update overhead: GIN indexes slow down INSERT/UPDATE (must update index). Real-world: Medium uses generated columns for article search (faster queries). Shopify uses GIN indexes for product search (100x faster). Use PostgreSQL FTS for < 1M documents, Elasticsearch for > 1M documents.
GIN indexes: 100x faster than sequential scan, essential for full-text search
Generated columns: Faster than expression indexes (pre-computed, no recalculation)
Query complexity: Simple queries (single word) fast, complex queries (multiple operators) slower
Document size: Keep < 1MB, large documents slow down indexing and search
Index size: GIN indexes are 30-50% of table size, plan storage accordingly
Update overhead: GIN indexes slow down INSERT/UPDATE (must update index)
Use LIMIT: Limit results to avoid returning too many rows (better performance)
Not creating GIN index: Sequential scan is 100x slower, always create GIN index
Using expression index instead of generated column: Expression recalculates on every query (slower)
Wrong language configuration: english for Spanish text produces bad results (wrong stemming)
Complex queries without testing: Multiple operators can be slow, test performance
Not using weighted search: Title and content treated equally (title should be higher priority)