PostgreSQL index methods support different operator families: GIN is common for composite values such as full-text and JSONB, GiST supports extensible search including ranges, and BRIN summarizes physically correlated blocks. Partial, expression, and included-column designs refine any suitable method. The query operator, data distribution, update pattern, and plan determine correctness and value.
An index supports particular operators through an operator class. “Index this JSON/vector/text” is incomplete until the query operator and semantics are known.
Active-ticket partial index:
Case-normalized business lookup:
The application must use equivalent semantics. Locale and normalization policy deserve design.
GIN commonly supports tsvector, arrays, and JSONB containment with appropriate operator classes. GiST supports ranges and exclusion constraints. BRIN can be tiny and useful for huge append-correlated tables but returns lossy candidate blocks. Hash has narrower equality use; B-tree usually remains more versatile.
INCLUDE stores non-key payload columns for potential index-only scans but increases size/write cost. Heap visibility still determines whether heap visits are avoided.
Hybrid retrieval needs a GIN full-text index plus a pgvector index, while tenant/version filters may need B-tree support. Combining index results and reranking is query design; one “AI index” does not solve lexical, semantic, policy, and freshness dimensions.
For each candidate, write the exact operator/predicate it supports. Capture before/after plans and sizes. Change the query predicate slightly and observe whether the partial index remains provably applicable.
Add a generated/stored search vector or maintained tsvector for ticket subjects and test a GIN-backed full-text query.
Acceptance criterion: lexical semantics are documented, plan uses the intended index at representative scale, and update behavior is verified.