Postgres Full Text Search Generator
Full text search in PostgreSQL takes four pieces that have to agree with each other: a tsvector built from the right columns with the right configuration, an index that matches that exact expression, a tsquery function suited to the input your users type, and a ranking expression that knows about your column weights. Get one of them wrong and the query still works — it just does a sequential scan or ranks results badly. Enter your table and searchable columns and this generator writes all four, plus the EXPLAIN and ts_stat queries you need to verify the index is really being used. Everything runs in your browser; no schema is uploaded.
Do more than postgres full text search generator — meet Chat2DB
Chat2DB is an AI-powered SQL client for Windows, macOS and Linux. Write SQL in natural language, format and optimize queries automatically, and manage MySQL, PostgreSQL, Oracle and 20+ other databases in one workspace.
How to use
- Enter the table name and list the searchable columns one per line, optionally followed by a weight letter (A is highest, D is lowest).
- Pick the text search configuration for your language, how the vector is stored (generated column, trigger or expression index) and the index method.
- Copy the DDL, the search query and the maintenance snippets, then run EXPLAIN ANALYZE to confirm PostgreSQL uses the new index.
Frequently asked questions
Should I use a generated column or a trigger for tsvector in PostgreSQL?
On PostgreSQL 12 and newer, use a stored generated column. It is declarative, cannot drift out of sync with the source columns, and needs no code to maintain. Use a trigger only when the vector depends on something a generated column cannot see — a value from another table, a lookup function that is not IMMUTABLE, or per-row logic — or when you are still on PostgreSQL 11 or older, where generated columns do not exist. An expression index is the third option: no extra column at all, but every query must repeat the indexed expression exactly or the index is ignored.
GIN or GiST for a tsvector index?
GIN for almost every case. GIN stores each lexeme once with a posting list of row pointers, so lookups are about three times faster than GiST and the results are exact. GiST is lossy: it stores a signature per row, produces false positives and PostgreSQL has to recheck each candidate row against the heap. GiST is smaller and cheaper to update, so it can win on tables with very heavy write traffic and modest search volume. If GIN updates are your bottleneck, tune fastupdate and gin_pending_list_limit before switching index types.
Why does my full text search query not use the index?
The three usual causes: the text search configuration in the query differs from the one in the index (to_tsvector('english', body) is a different expression from to_tsvector(body) with a session default), the query calls to_tsvector on a column instead of comparing the indexed column or expression, or the table is small enough that a sequential scan is genuinely cheaper. Run EXPLAIN (ANALYZE, BUFFERS) and check whether a Bitmap Index Scan appears. To inspect indexes, run EXPLAIN and browse tsvector data across PostgreSQL, MySQL and 20+ other engines in one client, use Chat2DB — download it at https://chat2db.ai/download or open https://app.chat2db.ai in a browser.
