Persisted vector
Product search vectors already exist before a search begins.
V3 keeps the linguistic retrieval introduced in V2, but moves document-vector construction to the write path and adds a PostgreSQL GIN inverted index for candidate lookup.
Search to inspect whether PostgreSQL chooses the GIN index, how many rows are retrieved, and how V3 compares with V2.
Product search vectors already exist before a search begins.
PostgreSQL rebuilds the vector when relevant product fields change.
An inverted index helps PostgreSQL locate matching lexemes efficiently.
Something went wrong.
An index existing does not guarantee the planner will use it.
GIN inverted index built over the persisted product search vector.
Determined from the actual PostgreSQL execution plan.
Bitmap, index-assisted or sequential retrieval.
Rows produced by the selected retrieval node.
Human-readable interpretation of
EXPLAIN ANALYZE.
Run a search to inspect PostgreSQL's selected execution strategy.
Time spent constructing the query plan.
PostgreSQL executor duration.
Rows rejected by filters after retrieval.
Pages found in PostgreSQL shared buffers.
Pages read into shared buffers.
Startup time for the selected node.
Total time spent inside the selected node.
V3 moves vector construction out of search requests and into product writes.
New products receive a search vector before the row is stored.
Search vectors are rebuilt when searchable product fields change.
Name, brand, category, tags and description trigger vector maintenance.
Triggers do not run during normal search requests.
Same FTS semantics. Different retrieval architecture.
| Version | Strategy | Results | App time | DB execution | Peak memory | Primary scan | Index |
|---|---|---|---|---|---|---|---|
| V2 | Runtime FTS vector | — | — | — | — | Sequential Scan | None |
| V3 | Persisted vector + GIN | — | — | — | — | — | — |
Matching products remain ordered using
ts_rank_cd().
V3 no longer rebuilds the complete product document vector during every search.
products.search_vector
PostgreSQL keeps the stored vector synchronized with searchable fields.
BEFORE INSERT OR UPDATE
PostgreSQL can locate matching lexemes without beginning from every product row.
USING GIN(search_vector)
GIN finds candidates. PostgreSQL still calculates relevance and sorts matches.
ts_rank_cd()
An index does not force a particular execution plan. PostgreSQL estimates the cost of available strategies and may prefer a sequential scan when a query matches a very large percentage of the table.
GIN is likely valuable.
Planner evaluates tradeoffs.
Sequential Scan may be cheaper.