Skip to content

This is the multi-page printable view of this section. .

Return to the regular view of this page.

Reference

SQL schema, indexing options, search options, and vector types in pgvecto.rs.

1 - Schema

Here is the schema provided by pgvecto.rs.

Here is the schema provided by pgvecto.rs.

List of data types

Name Description
vector vector, scalar type of which is binary32 defined in IEEE 754-2008
vecf16 vector, scalar type of which is binary16 defined in IEEE 754-2008
veci8 vector, scalar type of which is 8-bit Integer
svector sparse vector, scalar type of which is binary32 defined in IEEE 754-2008
bvector binary vector, a fixed-length bit string
vector_index_stat a composite type representing vector index statistics

List of operators

Name Left arg type Right arg type Result type Description
+ vector vector vector element-wise arithmetic
+ vecf16 vecf16 vecf16 element-wise arithmetic
+ veci8 veci8 veci8 element-wise arithmetic
+ svector svector svector element-wise arithmetic
- vector vector vector element-wise arithmetic
- vecf16 vecf16 vecf16 element-wise arithmetic
- veci8 veci8 veci8 element-wise arithmetic
- svector svector svector element-wise arithmetic
& bvector bvector bvector element-wise logical AND
| bvector bvector bvector element-wise logical OR
^ bvector bvector bvector element-wise logical XOR
= vector vector boolean dictionary order comparison
= vecf16 vecf16 boolean dictionary order comparison
= veci8 veci8 boolean dictionary order comparison
= svector svector boolean dictionary order comparison
= bvector bvector boolean dictionary order comparison
<> vector vector boolean dictionary order comparison
<> vecf16 vecf16 boolean dictionary order comparison
<> veci8 veci8 boolean dictionary order comparison
<> svector svector boolean dictionary order comparison
<> bvector bvector boolean dictionary order comparison
< vector vector boolean dictionary order comparison
< vecf16 vecf16 boolean dictionary order comparison
< veci8 veci8 boolean dictionary order comparison
< svector svector boolean dictionary order comparison
< bvector bvector boolean dictionary order comparison
> vector vector boolean dictionary order comparison
> vecf16 vecf16 boolean dictionary order comparison
> veci8 veci8 boolean dictionary order comparison
> svector svector boolean dictionary order comparison
> bvector bvector boolean dictionary order comparison
<= vector vector boolean dictionary order comparison
<= vecf16 vecf16 boolean dictionary order comparison
<= veci8 veci8 boolean dictionary order comparison
<= svector svector boolean dictionary order comparison
<= bvector bvector boolean dictionary order comparison
>= vector vector boolean dictionary order comparison
>= vecf16 vecf16 boolean dictionary order comparison
>= veci8 veci8 boolean dictionary order comparison
>= svector svector boolean dictionary order comparison
>= bvector bvector boolean dictionary order comparison
<-> vector vector real squared Euclidean distance
<-> vecf16 vecf16 real squared Euclidean distance
<-> veci8 veci8 real squared Euclidean distance
<-> svector svector real squared Euclidean distance
<-> bvector bvector real squared Euclidean distance
<#> vector vector real negative dot product
<#> vecf16 vecf16 real negative dot product
<#> veci8 veci8 real negative dot product
<#> svector svector real negative dot product
<#> bvector bvector real negative dot product
<=> vector vector real cosine distance
<=> vecf16 vecf16 real cosine distance
<=> veci8 veci8 real cosine distance
<=> svector svector real cosine distance
<=> bvector bvector real cosine distance
<~> bvector bvector real jaccard distance

List of functions

Name Argument type Result type Description
pgvectors_upgrade void Administration function for upgrading pgvecto.rs.
to_svector dims integer, index integer[], value real[] svector Construct a sparse vector from two arrays of indexes and values
binarize vector vector bvector Binarize a vector. All positive elements are set to 1, otherwise 0.
text2vec_openai input text, model text vector Embedding function for OpenAI embeddings API.
text2vec_openai_v3 input text vector Embedding function for OpenAI embeddings API. The model is set to text-embedding-3-small.

List of casts

Source type Target type Implicit?
real[] vector yes
vector real[] yes
vector vecf16 no
vecf16 vector no
vector veci8 no
veci8 vector no
vector svector no
svector vector no
vector bvector no
bvector vector no

List of access methods

Name Type Description
vectors Index pgvecto.rs vector index

List of operator families

AM Operator family Applicable types
vectors vector_cos_ops vector
vectors vector_dot_ops vector
vectors vector_l2_ops vector
vectors vecf16_cos_ops vecf16
vectors vecf16_dot_ops vecf16
vectors vecf16_l2_ops vecf16
vectors veci8_cos_ops veci8
vectors veci8_dot_ops veci8
vectors veci8_l2_ops veci8
vectors svector_cos_ops svector
vectors svector_dot_ops svector
vectors svector_l2_ops svector
vectors bvector_cos_ops bvector
vectors bvector_dot_ops bvector
vectors bvector_l2_ops bvector
vectors bvector_jaccard_ops bvector

List of operator classes

AM Input type Operator class Default? Description
vectors vector vector_l2_ops no squared Euclidean distance
vectors vector vector_dot_ops no negative dot product
vectors vector vector_cos_ops no cosine distance
vectors vecf16 vecf16_l2_ops no squared Euclidean distance
vectors vecf16 vecf16_dot_ops no negative dot product
vectors vecf16 vecf16_cos_ops no cosine distance
vectors veci8 veci8_l2_ops no squared Euclidean distance
vectors veci8 veci8_dot_ops no negative dot product
vectors veci8 veci8_cos_ops no cosine distance
vectors svector svector_l2_ops no squared Euclidean distance
vectors svector svector_dot_ops no negative dot product
vectors svector svector_cos_ops no cosine distance
vectors bvector bvector_l2_ops no squared Euclidean distance
vectors bvector bvector_dot_ops no negative dot product
vectors bvector bvector_cos_ops no cosine distance
vectors bvector bvector_jaccard_ops no jaccard distance

List of views

Name Description
pg_vector_index_stat A view provided for vector index statistics

2 - Indexing Options

We utilize TOML syntax to express the index’s configuration. Here’s what each key in the configuration signifies:

We utilize TOML syntax to express the index’s configuration. Here’s what each key in the configuration signifies:

Key Type Description
segment table Options for segments.
optimizing table Options for background optimizing.
indexing table The algorithm to be used for indexing.

Options for table segment

Key Type Range Default Description
max_growing_segment_size integer [1, 4_000_000_000] 20_000 Maximum size of unindexed vectors.
max_sealed_segment_size integer [1, 4_000_000_000] 1_000_000 Maximum size of vectors for indexing.

Options for table optimizing

Key Type Range Default Description
optimizing_threads integer [1, 65535] sqrt of the number of cores Maximum threads for indexing.
sealing_secs integer [1, 60] 60 See below.
sealing_size integer [1, 4_000_000_000] 1 See below.

If a write segment larger than sealing_size do not accept new data for sealing_secs seconds, the write segment will be turned to a sealed segment.

Options for table indexing

Key Type Description
flat table If this table is set, brute force algorithm will be used for the index.
ivf table If this table is set, IVF will be used for the index.
hnsw table If this table is set, HNSW will be used for the index.

You can choose only one algorithm in above indexing algorithms. Default value is hnsw.

Options for table flat

Key Type Description
quantization table The algorithm to be used for quantization.

Options for table ivf

Key Type Range Default Description
nlist integer [1, 1_000_000] 1000 Number of cluster units.
nsample integer [1, 1_000_000] 65536 Number of samples for K-Means clustering.
least_iterations integer [1, 1_000_000] 16 Least iterations for K-Means clustering.
iterations integer [1, 1_000_000] 500 Max iterations for K-Means clustering.
quantization table The quantization algorithm to be used.

Options for table hnsw

Key Type Range Default Description
m integer [4, 128] 12 Maximum degree of the node.
ef_construction integer [10, 2000] 300 Search scope in building.
quantization table The quantization algorithm to be used.

Options for table quantization

Key Type Description
trivial table If this table is set, no quantization is used.
scalar table If this table is set, scalar quantization is used.
product table If this table is set, product quantization is used.

You can choose only one algorithm in above indexing algorithms. Default value is trivial.

Options for table product

Key Type Range Default Description
sample integer [1, 1_000_000] 65535 Samples to be used for quantization.
ratio enum "x4", "x8", "x16", "x32", "x64" "x4" Compression ratio for quantization.

Compression ratio is how many memory you are saved for saving vectors. For example, "x4" is 14\frac{1}{4} compared to before. If you are creating indexes on vecf16, "x4" is 12\frac{1}{2} compared to before.

3 - Search Options

Search options are specified by PostgreSQL GUC.

Search options are specified by PostgreSQL GUC.

Options for ivf

These options only work for IVF algorithm. Refer to Indexing.

Option Type Range Default Description
vectors.ivf_nprobe integer [1, 1_000_000] 10 Number of lists to scan.

Options for hnsw

These options only work for HNSW algorithm. Refer to Indexing.

Option Type Range Default Description
vectors.hnsw_ef_search integer [1, 65535] 100 Search scope of HNSW.

Other Options

Query options for search mode: .

Option Type Range Default Description
vectors.search_mode enum "basic", "vbase" "vbase" Search mode, Refer to Search
vectors.pgvector_compatibility boolean off Enable or disable pgvector compatibility, Refer to pgvector compatibility
vectors.enable_index boolean on Enable or disable the query planner’s use of vector types.

4 - Vector Types

In the previous sections Indexing and Search, we encountered the vector type. This section will explore additional vector types and their applications in the re

In the previous sections Indexing and Search, we encountered the vector type. This section will explore additional vector types and their applications in the realm of vector search.

Low-precision Indexing

since v0.3.0

To improve the speed of queries on the vector column, consider creating a low-precision index using vecf16, veci8, or bvector types instead of a vector type.

CREATE TABLE t (val vector(3));
INSERT INTO t (val) SELECT ARRAY[random(), random(), random()]::real[] FROM generate_series(1, 1000);

-- Create bvector index at vector column
-- Warning: Float32 vectors are truncated to 
--          integers of either 0 or 1 during index construction
CREATE INDEX lp_bin ON t USING vectors ((binarize(val)::bvector(3)) bvector_l2_ops);

-- Create vecf16 index at vector column
CREATE INDEX lp_f16 ON t USING vectors ((val::vecf16(3)) vecf16_l2_ops);

-- Create veci8 index at vector column
-- Warning: Float32 vectors are truncated to 
--          integers ranging from -128 to 127 during index construction
CREATE INDEX lp_i8 ON t USING vectors ((val::veci8(3)) veci8_l2_ops);

Shortening Embedding

since v0.3.0

Certain embedding models like OpenAI text-embedding-3-small support shortening embeddings, which involves removing some numbers from the end of the sequence without losing the embedding’s concept-representing properties.

In some cases, it may be necessary to change the embedding dimension after generation. The pgvecto.rs offers an approach to query by shortened embeddings.

CREATE TABLE t (val vector(3));
INSERT INTO t (val) SELECT ARRAY[random(), random(), random()]::real[] FROM generate_series(1, 1000);
CREATE INDEX ON t USING vectors (val vector_l2_ops);

-- Measure distance using only the first two dimensions
SELECT * from t ORDER BY (val[:2])::vector(2) <-> '[3, 2]'::vector;

Shortened embeddings are supported by all data types in pgvecto.rs since version v0.3.0.

Casts

This diagram shows the conversion between different data types, where the types connected by arrows can be cast to each other:

Among them, ARRAY is a native type of postgreSQL, others are types defined by pgvecto.rs.

Here are some examples of vector type casting:

-- OK: String ⇒ vector
SELECT '{1,2,3}'::vector;

-- OK: vector ⇒ ARRAY
SELECT '{1,2,3}'::vector::real[];

-- OK: ARRAY ⇒ vector ⇒ bvector
SELECT ARRAY[1.0 ,0 ,0]::real[]::vector::bvector;

-- ERROR: cannot cast type vecf16 to veci8
SELECT '[3, 2]'::vecf16::veci8;

-- OK: vecf16 ⇒ vector ⇒ veci8
SELECT '[3, 2]'::vecf16::vector::veci8;

4.1 - Half-Precision Vector: `vecf16`

Stored as a half-precision number format, vecf16 takes advantage of the 16-bit float, which uses half the memory and bandwidth compared to vector.

Stored as a half-precision number format, vecf16 takes advantage of the 16-bit float, which uses half the memory and bandwidth compared to vector.

Here’s an example of creating a table with a vecf16 column and inserting values:

CREATE TABLE items (
  id bigserial PRIMARY KEY,
  embedding vecf16(3) NOT NULL
);

INSERT INTO items (embedding) VALUES ('[0.1, 0.2, 0]'), ('[0, 0.1, 0.2]');

Index can be created on vecf16 type as well.

CREATE INDEX your_index_name ON items USING vectors (embedding vecf16_l2_ops);

SELECT * FROM items ORDER BY embedding <-> '[0.3,0.2,0.1]' LIMIT 1;

We support three operators to calculate the distance between two vecf16 values.

  • <-> (vecf16_l2_ops): squared Euclidean distance, defined as Σ(xi−yi)2\Sigma (x_i - y_i) ^ 2.
  • <#> (vecf16_dot_ops): negative dot product, defined as −Σxiyi- \Sigma x_iy_i.
  • <=> (vecf16_cos_ops): cosine distance, defined as 1−ΣxiyiΣxi2Σyi21 - \frac{\Sigma x_iy_i}{\sqrt{\Sigma x_i^2 \Sigma y_i^2}}.

4.2 - 8-Bit Integer Vector: `veci8`

Int8 is a data type used to represent signed integers. It stands for “integer 8-bit” and typically uses 8 bits of memory to store a value. This allows it to rep
since v0.3.0

Int8 is a data type used to represent signed integers. It stands for “integer 8-bit” and typically uses 8 bits of memory to store a value. This allows it to represent integer values ranging from -128 to 127.

Since each element in the vector only requires 8 bits (1 byte) of memory, veci8 can help reduce the overall memory footprint of your program.

Here’s an example of creating a table with a veci8 column and inserting values:

CREATE TABLE items (
  id bigserial PRIMARY KEY,
  embedding veci8(3) NOT NULL
);

INSERT INTO items (embedding) VALUES ('[1, 2, 0]'), ('[-1, 15, -2]');

Index can be created on veci8 type as well.

CREATE INDEX your_index_name ON items USING vectors (embedding veci8_l2_ops);

SELECT * FROM items ORDER BY embedding <-> '[0.3,0.2,0.1]' LIMIT 1;

We support three operators to calculate the distance between two veci8 values.

  • <-> (veci8_l2_ops): squared Euclidean distance, defined as Σ(xi−yi)2\Sigma (x_i - y_i) ^ 2.
  • <#> (veci8_dot_ops): negative dot product, defined as −Σxiyi- \Sigma x_iy_i.
  • <=> (veci8_cos_ops): cosine distance, defined as 1−ΣxiyiΣxi2Σyi21 - \frac{\Sigma x_iy_i}{\sqrt{\Sigma x_i^2 \Sigma y_i^2}}.

4.3 - Sparse Vector: `svector`

Unlike dense vectors, sparse vectors are very high-dimensional but contain few non-zero values.
since v0.3.0

Unlike dense vectors, sparse vectors are very high-dimensional but contain few non-zero values.

Typically, sparse vectors can be created from:

  • Word co-occurrence matrices
  • Term frequency-inverse document frequency (TF-IDF) vectors
  • User-item interaction matrices
  • Network adjacency matrices

Sparse vectors in pgvecto.rs are called svector.

Here’s an example of creating a table with a svector column and inserting values:

CREATE TABLE items (
  id bigserial PRIMARY KEY,
  embedding svector(10) NOT NULL
);

INSERT INTO items (embedding) VALUES ('[0.1,0,0,0,0,0,0,0,0,0]'), ('[0,0,0,0,0,0,0,0,0,0.5]');

Index can be created on svector type as well.

CREATE INDEX your_index_name ON items USING vectors (embedding svector_l2_ops);

SELECT * FROM items ORDER BY embedding <-> '[0.3,0,0,0,0,0,0,0,0,0]' LIMIT 1;

We support three operators to calculate the distance between two svector values.

  • <-> (svector_l2_ops): squared Euclidean distance, defined as Σ(xi−yi)2\Sigma (x_i - y_i) ^ 2.
  • <#> (svector_dot_ops): negative dot product, defined as −Σxiyi- \Sigma x_iy_i.
  • <=> (svector_cos_ops): cosine distance, defined as 1−ΣxiyiΣxi2Σyi21 - \frac{\Sigma x_iy_i}{\sqrt{\Sigma x_i^2 \Sigma y_i^2}}.

There is also a function to_svector to create a svector. It will set the value at the specified position.

F(index)={value[v]∃v∈N:position[v]=index0else F(index)=\left\{ \begin{array}{rcl} value[v] & & {\exists v \in \mathbb{N}: position[v] = index }\\ 0 & & {else}\\ \end{array} \right.
-- to_svector(dim: INTEGER, position: ARRAY, value: ARRAY) -> svector
SELECT to_svector(5, '{0, 4}', '{0.3, 0.5}');
-- [0.3, 0, 0, 0, 0.5]

4.4 - Binary Vector: `bvector`

The bvector type is a binary vector type in pgvecto.rs. It represents a binary vector, which is a vector where each component can take on two possible values, t
since v0.3.0

The bvector type is a binary vector type in pgvecto.rs. It represents a binary vector, which is a vector where each component can take on two possible values, typically 0 and 1.

Here’s an example of creating a table with a bvector column and inserting values:

CREATE TABLE items (
  id bigserial PRIMARY KEY,
  embedding bvector(3) NOT NULL
);

INSERT INTO items (embedding) VALUES ('[1,0,1]'), ('[0,1,0]');

Index can be created on bvector type as well.

CREATE INDEX your_index_name ON items USING vectors (embedding bvector_l2_ops);

SELECT * FROM items ORDER BY embedding <-> '[1,0,1]' LIMIT 5;

We support three operators to calculate the distance between two bvector values.

  • <-> (bvector_l2_ops): squared Euclidean distance, defined as Σ(xi−yi)2\Sigma (x_i - y_i) ^ 2. The Hamming distance is equivalent to the squared Euclidean distance for binary vectors.
  • <#> (bvector_dot_ops): negative dot product, defined as −Σxiyi- \Sigma x_iy_i.
  • <=> (bvector_cos_ops): cosine distance, defined as 1−ΣxiyiΣxi2Σyi21 - \frac{\Sigma x_iy_i}{\sqrt{\Sigma x_i^2 \Sigma y_i^2}}.
  • <~> (bvector_jaccard_ops): Jaccard distance, defined as 1−∣X∩Y∣∣X∪Y∣1 - \frac{|X\cap Y|}{|X\cup Y|}.

There is also a function binarize to build bvector from vector. It truncates vector elements to integers of 0 or 1.

F(element)={0element<11element≥1 F(element)=\left\{ \begin{array}{rcl} 0 & & {element < 1}\\ 1 & & {element \geq 1}\\ \end{array} \right.
-- binarize(source: vector) -> bvector
SELECT binarize('[-2, -1, 0, 1, 2]'::vector);
-- [0, 0, 0, 1, 1]

Performance

The bvector type is optimized for storage and performance. It uses a bit-packed representation to store the binary vector. The distance calculation is also optimized for binary vectors.

Here are some performance benchmarks for the bvector type. We use the dbpedia-entities-openai3-text-embedding-3-large-3072-1M dataset for the benchmark. The VM is n2-standard-8 (8 vCPUs, 32 GB memory) on Google Cloud.

We upsert 1M binary vectors into the table and then run a KNN query for each embedding. It only takes about 600MB memory to index 1M binary vectors, while the vector type takes about 18GB memory to index the same number of vectors.

bvector

We can see that the bvector’s accuracy is not as good as the vector type, but it exceeds 95% if we adopt adaptive retrieval.