Reference, Tuning & FAQ
Complete SQL function reference, GUC configuration parameters, performance tuning, monitoring, and FAQ for pgvector.
SQL Function Reference
Vector Functions
| Function | Return Type | Description |
|---|---|---|
l2_distance(a, b) |
float8 |
Euclidean (L2) distance between a and b (vector, halfvec, sparsevec) |
inner_product(a, b) |
float8 |
Inner (dot) product (vector, halfvec, sparsevec) |
cosine_distance(a, b) |
float8 |
Cosine distance (vector, halfvec, sparsevec) |
l1_distance(a, b) |
float8 |
Manhattan (L1) distance (\sum |
hamming_distance(a, b) |
float8 |
Hamming distance between two bit vectors |
jaccard_distance(a, b) |
float8 |
Jaccard distance between two bit vectors |
vector_dims(a) |
integer |
Number of dimensions in a (vector, halfvec, sparsevec) |
vector_norm(a) |
float8 |
Euclidean norm (vector, halfvec, sparsevec) |
l2_normalize(a) |
same as input | Normalize vector a to unit L2 length (vector, halfvec, sparsevec) |
binary_quantize(a) |
bit |
Quantize each element of vector or halfvec to 1 () or 0 () |
subvector(a, start, count) |
same as input | Extract count dimensions starting at 1-based index start (vector, halfvec) |
Element-Wise Arithmetic Operators
a + b: Element-wise addition (vector,halfvec)a - b: Element-wise subtraction (vector,halfvec)a * b: Element-wise multiplication (vector,halfvec)a || b: Vector concatenation (vector,halfvec)
GUC Parameters
| Parameter | Type / Allowed Values | Default | Description |
|---|---|---|---|
hnsw.ef_search |
integer (1–1000) |
40 |
Size of the dynamic candidate list during HNSW search |
hnsw.iterative_scan |
off, relaxed_order, strict_order |
off |
Automatically scan more HNSW tuples when WHERE filters reduce results below LIMIT |
hnsw.max_scan_tuples |
integer |
20000 |
Maximum tuples visited during an HNSW iterative scan |
hnsw.scan_mem_multiplier |
real |
1 |
Multiple of work_mem used for HNSW iterative scan state |
ivfflat.probes |
integer (1–lists) |
1 |
Number of inverted lists probed during an IVFFlat query |
ivfflat.iterative_scan |
off, relaxed_order |
off |
Automatically probe additional IVFFlat lists when WHERE filters reduce results below LIMIT |
ivfflat.max_probes |
integer |
32768 |
Maximum lists probed during an IVFFlat iterative scan |
Performance Tuning & Monitoring
1. Check Index Size
2. Inspect Query Execution Plans
Use EXPLAIN ANALYZE to confirm whether an index scan is chosen and measure execution latency:
3. Monitor Slow Queries with pg_stat_statements
4. Measure Recall
Compare approximate index results against exact sequential scan results inside a transaction:
Frequently Asked Questions (FAQ)
Why isn’t my query using the vector index?
- Missing
ORDER BY ... LIMIT: Index scans require both anORDER BY <operator>and aLIMITclause. - Mismatched operator class: The query operator must match the index operator class (
<->requiresvector_l2_ops,<#>requiresvector_ip_ops,<=>requiresvector_cosine_ops). - Small table cost estimation: On small tables, PostgreSQL’s planner may correctly determine that a sequential scan is cheaper than an index scan. To force index usage during testing, run
SET LOCAL enable_seqscan = off;.
How do I index vectors with more than 2,000 dimensions?
pgvector HNSW and IVFFlat indexes cap vector columns at 2,000 dimensions because PostgreSQL index tuples cannot exceed 8 KB page limits. You have three options:
- Install
vchord:vchord’svchordrqindex supports up to 60,000 dimensions directly onvectorandhalfveccolumns. - Half-precision expression indexing: Cast to
halfvec((embedding::halfvec(3072)) halfvec_l2_ops) to index up to 4,000 dimensions. - Binary quantization: Use
(binary_quantize(embedding)::bit(N)) bit_hamming_opsto index up to 64,000 dimensions.
Can I store vectors with different dimensions in the same column?
Yes, declare the column without a dimension modifier (embedding vector), though you can only create an index on rows that share the same dimension via a partial expression index:
Do vectors contain NULL or NaN / Infinity?
Vectors cannot contain NULL, NaN, or Infinity elements. A whole column value can be NULL; note that NULL vectors are not indexed in IVFFlat and are sorted last by default unless NULLS FIRST is specified.