pgvector Index and Schema Generator
Pick your embedding dimensions, distance metric and index type, and this generator writes the pgvector SQL for you: CREATE EXTENSION, the table or ALTER TABLE with a vector, halfvec, bit or sparsevec column, an HNSW or IVFFlat index with the right operator class, and the nearest-neighbour query whose ORDER BY matches that index. It also suggests IVFFlat lists/probes from your row count and emits EXPLAIN and recall checks. Everything runs in your browser — no embeddings are uploaded.
Do more than pgvector index and schema 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 and column, the embedding dimensions (1536 for OpenAI text-embedding-3-small, 768 for many open models) and the column type.
- Choose the distance metric your model was trained for — cosine for normalised embeddings, L2 for raw Euclidean, inner product for dot-product models — then pick HNSW or IVFFlat and tune m, ef_construction or lists.
- Copy the schema script, the KNN query and the verification queries into psql or Chat2DB, then confirm with EXPLAIN that the index is used.
Frequently asked questions
Should I use an HNSW or an IVFFlat index in pgvector?
HNSW builds a graph and gives better recall at the same speed, works on an empty table, and is the default choice for most applications; the trade-off is a slower build and more memory. IVFFlat clusters vectors into lists and builds much faster with a smaller index, but it must be created after the data is loaded (an empty table produces meaningless centroids) and needs rebuilding when the data distribution shifts. Start with HNSW using m = 16 and ef_construction = 64, then raise hnsw.ef_search at query time until recall is acceptable.
Why does my pgvector query do a sequential scan instead of using the index?
An approximate index only answers ORDER BY queries that use the exact operator it was built for: an index created with vector_cosine_ops serves ORDER BY embedding <=> $1 and nothing else, so switching to <-> or wrapping the column in a function forces a scan. Other common causes are a missing LIMIT, a query that filters most rows away so the planner prefers a scan, a dimension mismatch between the column and the literal, or an index that was built on a different column type. Run EXPLAIN (ANALYZE, BUFFERS) and check for "Index Scan using ..._hnsw_idx".
How do I combine vector search with normal WHERE filters in PostgreSQL?
Postgres can apply a filter and an ANN index together, but the index returns a fixed number of candidates first, so a very selective filter can leave fewer rows than your LIMIT. Three patterns work well: add a B-tree index on the filter column and over-fetch (LIMIT 100, filter, keep 10); build a partial HNSW index with a WHERE clause per tenant or category; or pre-filter into a CTE when the subset is small enough for exact search. Chat2DB, a free AI-powered SQL client, is handy for comparing the plans of these variants side by side — download it at https://chat2db.ai/download or use https://app.chat2db.ai.
