IVFFlat
An IVFFlat index divides vectors into lists, and then searches a subset of those lists that are closest to the query vector. It has faster build times and uses less memory than HNSW, but has lower query performance (in terms of speed-recall tradeoff).
Three keys to achieving good recall are:
- Create the index after the table has some data
- Choose an appropriate number of lists - a good place to start is
rows / 1000for up to 1M rows andsqrt(rows)for over 1M rows - When querying, specify an appropriate number of probes (higher is better for recall, lower is better for speed) - a good place to start is
sqrt(lists)
Add an index for each distance function you want to use.
L2 distance
CREATE INDEX ON items USING ivfflat (embedding vector_l2_ops) WITH (lists = 100);
Note: Use halfvec_l2_ops for halfvec (and similar with the other distance functions)
Inner product
CREATE INDEX ON items USING ivfflat (embedding vector_ip_ops) WITH (lists = 100);
Cosine distance
CREATE INDEX ON items USING ivfflat (embedding vector_cosine_ops) WITH (lists = 100);
Hamming distance
CREATE INDEX ON items USING ivfflat (embedding bit_hamming_ops) WITH (lists = 100);
Supported types are:
vector- up to 2,000 dimensionshalfvec- up to 4,000 dimensionsbit- up to 64,000 dimensions
Query Options
Specify the number of probes (1 by default)
SET ivfflat.probes = 10;
A higher value provides better recall at the cost of speed, and it can be set to the number of lists for exact nearest neighbor search (at which point the planner won’t use the index)
Use SET LOCAL inside a transaction to set it for a single query
BEGIN;
SET LOCAL ivfflat.probes = 10;
SELECT ...
COMMIT;
Index Build Time
Speed up index creation on large tables by increasing the number of parallel workers (2 by default)
SET max_parallel_maintenance_workers = 7; -- plus leader
For a large number of workers, you may also need to increase max_parallel_workers (8 by default)
Indexing Progress
Check indexing progress
SELECT phase, round(100.0 * tuples_done / nullif(tuples_total, 0), 1) AS "%" FROM pg_stat_progress_create_index;
The phases for IVFFlat are:
initializingperforming k-meansassigning tuplesloading tuples
Note: % is only populated during the loading tuples phase