You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -5,25 +5,51 @@ VectorChord's index type `vchordrq` divides vectors into lists and searches only
5
5
To build a vector index, start by creating a table named `items` with an `embedding` column of type `vector(n)`, then populate it with sample data.
6
6
7
7
```sql
8
-
CREATETABLEitems (embedding vector(3));
8
+
CREATETABLEitems (id bigserialPRIMARY KEY, embedding vector(3));
9
9
INSERT INTO items (embedding) SELECT ARRAY[random(), random(), random()]::real[] FROM generate_series(1, 1000);
10
10
```
11
11
12
-
To create the VectorChord index, you can use the following SQL.
12
+
To create a `vchordrq` index, you can use the following SQL.
13
+
14
+
```sql
15
+
CREATEINDEXON items USING vchordrq (embedding vector_l2_ops);
16
+
```
17
+
18
+
After the index is built, you can perform a vector search using it to retrieve the $10$ nearest neighbors to a vector.
19
+
20
+
```sql
21
+
SELECT*FROM items ORDER BY embedding <->'[3,1,2]'LIMIT10;
22
+
```
23
+
24
+
You can also add filters to vector search queries as needed.
25
+
26
+
```sql
27
+
SELECT*FROM items WHERE id % 7<>0ORDER BY embedding <->'[3,1,2]'LIMIT10;
28
+
```
29
+
30
+
## Tuning
31
+
32
+
When there are less than $100,000$ rows in the table, you usually don't need to set parameters for search and query.
33
+
34
+
```sql
35
+
CREATEINDEXON items USING vchordrq (embedding vector_l2_ops);
36
+
37
+
SELECT*FROM items ORDER BY embedding <->'[3,1,2]'LIMIT10;
38
+
```
39
+
40
+
However, as the number of rows grows, partitioning becomes necessary and can be configured using index options. `options` are specified using a [TOML: Tom's Obvious Minimal Language](https://toml.io/) string. You can refer to [#Index Options](#indexing-options) for more information.
13
41
14
42
```sql
15
43
CREATEINDEXON items USING vchordrq (embedding vector_l2_ops) WITH (options = $$
16
-
residual_quantization = true
17
44
[build.internal]
18
45
lists = [1000]
19
-
build_threads =16
20
46
$$);
47
+
48
+
SETvchordrq.probes TO '10';
49
+
SELECT*FROM items ORDER BY embedding <->'[3,1,2]'LIMIT10;
21
50
```
22
51
23
-
> [!NOTE]
24
-
> -`options` are specified using a [TOML: Tom's Obvious Minimal Language](https://toml.io/) string. You can refer to [#Index Options](#indexing-options) for more information.
25
-
> - When dealing with large tables, it will cost huge time and memory for `build.internal`. You can refer to [External Build](external-index-precomputation) to have a better experience.
26
-
> - The parameter `lists` should be configured based on the number of rows. The following table provides guidance for this selection. When searching, set `vchordrq.probes` based on the value of `lists`.
52
+
The parameter `lists` should be tuned based on the number of rows. The following table provides guidelines for choosing an appropriate value. When querying, choose `vchordrq.probes` accordingly.
27
53
28
54
| Number of Rows $N$ | Recommended Number of Partitions $L$ | Example `lists`|
Then the index will be built internally, and you can perform a vector search with the index.
61
+
The process of building an index involves two steps: partitioning the vector space first, and then inserting rows into the index. The first step, partitioning the vector space, can be sped up using multiple threads.
36
62
37
63
```sql
38
-
SETvchordrq.probes='10';
39
-
SELECT*FROM items ORDER BY embedding <->'[3,1,2]'LIMIT5;
64
+
CREATEINDEXON items USING vchordrq (embedding vector_l2_ops) WITH (options = $$
65
+
[build.internal]
66
+
lists = [1000]
67
+
build_threads =8
68
+
$$);
69
+
70
+
SETvchordrq.probes TO '10';
71
+
SELECT*FROM items ORDER BY embedding <->'[3,1,2]'LIMIT10;
72
+
```
73
+
74
+
The second step, inserting rows, can be parallelized using multiple processes. Refer to [PostgreSQL Tuning](performance-tuning.md#indexing).
75
+
76
+
For most datasets using cosine similarity, enabling `residual_quantization` and `build.internal.spherical_centroids` improves both QPS and recall.
77
+
78
+
```sql
79
+
CREATEINDEXON items USING vchordrq (embedding vector_cosine_ops) WITH (options = $$
80
+
residual_quantization = true
81
+
[build.internal]
82
+
lists = [1000]
83
+
spherical_centroids = true
84
+
build_threads =8
85
+
$$);
86
+
87
+
SETvchordrq.probes TO '10';
88
+
SELECT*FROM items ORDER BY embedding <=>'[3,1,2]'LIMIT10;
89
+
```
90
+
91
+
For large tables, the `build.internal` process costs huge time and memory. You can refer to [External Build](external-index-precomputation) to have a better experience.
92
+
93
+
For large tables, you may opt to use more shared memory to accelerate the process by setting `build.pin` to `true`.
94
+
95
+
```sql
96
+
CREATEINDEXON items USING vchordrq (embedding vector_l2_ops) WITH (options = $$
- Description: This index parameter determines whether shared memory is used for indexing. For large tables, you can choose to enable this option to speed up the build process.
153
+
- Type: boolean
154
+
- Default: `false`
155
+
- Example:
156
+
-`build.pin = false` means that shared memory is not used.
157
+
-`build.pin = true` means that shared memory is used.
@@ -88,7 +169,7 @@ The operator classes for `MaxSim` have been available only since version `0.3.0`
88
169
-`build.internal.lists = []` means that the vector space is not partitioned.
89
170
-`build.internal.lists = [4096]` means the vector space is divided into $4096$ cells.
90
171
-`build.internal.lists = [4096, 262144]` means the vector space is divided into $4096$ cells, and those cells are further divided into $262144$ smaller cells.
91
-
- Note: The index partitions the vector space into multiple Voronoi cells using centroids, iteratively creating a hierarchical space partition tree. Each leaf node in this tree represents a region with an associated list storing vectors in that region. During insertion, vectors are placed in lists corresponding to their appropriate leaf nodes. For queries, the index optimizes search by excluding lists whose leaf nodes are distant from the query vector, effectively pruning the search space. If the length of `lists` is $1$, the `lists` option should be no less than $4 * \sqrt{N}$, where $N$ is the number of vectors in the table.
172
+
- Note: The index partitions the vector space into multiple Voronoi cells based on centroids, iteratively creating a hierarchical space partition tree. Each leaf node in this tree represents a region with an associated list storing vectors in that region. During insertion, vectors are placed in lists corresponding to their appropriate leaf nodes. For queries, the index optimizes search by excluding lists whose leaf nodes are distant from the query vector, effectively pruning the search space. If the length of `lists` is $1$, the `lists` option should be no less than $4 * \sqrt{N}$, where $N$ is the number of vectors in the table.
92
173
93
174
#### `build.internal.spherical_centroids`
94
175
@@ -120,7 +201,7 @@ The operator classes for `MaxSim` have been available only since version `0.3.0`
120
201
-`build.internal.kmeans_iterations = 10` means that the K-means algorithm performs $10$ iterations.
121
202
-`build.internal.kmeans_iterations = 100` means that the K-means algorithm performs $100$ iterations.
- Description: This index parameter determines the number of threads used by K-means algorithm. The higher this value, the faster the build, and greater load on the server in building.
126
207
- Type: integer
@@ -129,3 +210,40 @@ The operator classes for `MaxSim` have been available only since version `0.3.0`
129
210
- Example:
130
211
-`build.internal.build_threads = 1` means that the K-means algorithm uses $1$ thread.
131
212
-`build.internal.build_threads = 4` means that the K-means algorithm uses $4$ threads.
- Description: This GUC parameter `vchordrq.probes` controls how the vector space assists in query pruning. The more probes, the more accurate the search, but also the slower it is.
219
+
- Type: list of integers
220
+
- Default:
221
+
-`` <badgetype="tip"text="since v0.3.0" />
222
+
-`10` <badgetype="tip"text="until v0.2.2: the default value was 10 before `lists` defaulted to empty" />
223
+
- Example:
224
+
-`SET vchordrq.probes = 1` means that only one probe is used.
225
+
-`SET vchordrq.probes = 10` means that ten probes are used.
226
+
- Note: The default value is an empty list. The length of this option must match the length of `lists`.
227
+
- If `lists = []`, then probes must be ``.
228
+
- If `lists = [11, 22]`, then probes can be `2,4` or `4,8`. It must not be incorrectly shaped, for example, ``, `3`, `7,8,9`, `5,5,5,5`.
229
+
230
+
#### `vchordrq.epsilon`
231
+
232
+
- Description: Even after pruning, the number of retrieved vectors remains substantial. The index employs the RaBitQ algorithm to quantize vectors into bit vectors, which require just $\frac{1}{32}$ the memory of single-precision floating-point vectors. Most computations are integer-based, leading to faster processing. Unlike conventional quantization algorithms, RaBitQ estimates not only distances but also their lower bounds. The index computes the lower bound for each vector and dynamically adjusts the number of vectors needing recalculated distances, based on the query count, thus balancing performance and accuracy. The GUC parameter `vchordrq.epsilon` controls the conservativeness of the lower bounds of distances. The higher the value, the higher the accuracy, but the worse the performance. The default value tends to favor higher accuracy than needed for most use cases, so you can try lowering this parameter to achieve better performance.
233
+
- Type: float
234
+
- Default: `1.9`
235
+
- Domain: `[0.0, 4.0]`
236
+
- Example:
237
+
-`SET vchordrq.epsilon = 0.1` indicates you are using a very optimistic lower bound estimation. You set it this way because your dataset is not sensitive to the lower bound estimation, for the precision you need.
238
+
-`SET vchordrq.epsilon = 4.0` indicates you are using a very pessimistic lower bound estimation. You set it this way because your dataset is not very sensitive to the lower bound estimation, for the precision you need.
239
+
240
+
#### `vchordrq.prewarm_dim` <badgetype="danger"text="deprecated in v0.4.0" />
241
+
242
+
- Description: The `vchordrq.prewarm_dim` GUC parameter is used to precompute the RaBitQ projection matrix for the specified dimensions. This can help to reduce the latency of the first query after the PostgreSQL cluster is started.
243
+
- Type: list of integers
244
+
- Default: `64,128,256,384,512,768,1024,1536`
245
+
- Example:
246
+
-`ALTER SYSTEM SET vchordrq.prewarm_dim = '64,128'` means that the projection matrix will be precomputed for dimensions 64 and 128.
247
+
- Note:
248
+
- This setting requires a database restart to take effect.
249
+
- Since `v0.4.0`, a new algorithm made this option obsolete.
0 commit comments