Skip to content

Commit d8855af

Browse files
committed
refactor
Signed-off-by: usamoi <[email protected]>
1 parent 0b7f980 commit d8855af

File tree

14 files changed

+187
-153
lines changed

14 files changed

+187
-153
lines changed

.vitepress/config.mts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ export default defineConfig({
2424
'pgvecto_rs/:dir/:page*': ':dir/:page*',
2525
'vectorchord/usage/multi-vector-retrieval.md': 'vectorchord/usage/indexing-with-maxsim-operators.md',
2626
'vectorchord/usage/similarity-filter.md': 'vectorchord/usage/range-query.md',
27+
'vectorchord/usage/postgresql-tuning.md': 'vectorchord/usage/performance-tuning.md',
2728
'vectorchord/usage/external-build.md': 'vectorchord/usage/external-index-precomputation.md',
2829
},
2930
head: [
@@ -189,10 +190,9 @@ export default defineConfig({
189190
collapsed: false,
190191
items: [
191192
{ text: 'Indexing', link: '/vectorchord/usage/indexing' },
192-
{ text: 'Search', link: '/vectorchord/usage/search' },
193193
{ text: 'Multi-Vector Retrieval', link: '/vectorchord/usage/indexing-with-maxsim-operators' },
194194
{ text: 'Similarity Filter', link: '/vectorchord/usage/range-query' },
195-
{ text: 'Performance Tuning', link: '/vectorchord/usage/performance-tuning' },
195+
{ text: 'PostgreSQL Tuning', link: '/vectorchord/usage/performance-tuning' },
196196
{ text: 'Monitoring', link: '/vectorchord/usage/monitoring' },
197197
{ text: 'Prewarm', link: '/vectorchord/usage/prewarm' },
198198
{ text: 'Prefilter', link: '/vectorchord/usage/prefilter' },

lychee.toml

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,16 @@ user_agent = "curl/8.1.2"
33
include_fragments = true
44
accept = [
55
200,
6-
403, # forbidden, mainly for OpenAI
7-
999, # LinkedIn
6+
403, # forbidden, mainly for OpenAI
7+
999, # LinkedIn
88
]
99
remap = [
10-
"(https://github.com/[^/]+/[^/]+/blob/[^#]+)#[a-zA-Z0-9._-]* $1", # remove fragment from GitHub **blob** URLS
11-
"(https://github.com/[^/]+/[^/]+/tree/[^#]+)#[a-zA-Z0-9._-]* $1", # remove fragment from GitHub **main** URLS
10+
"(https://github.com/[^/]+/[^/]+/blob/[^#]+)#[a-zA-Z0-9._-]* $1", # remove fragment from GitHub **blob** URLS
11+
"(https://github.com/[^/]+/[^/]+/tree/[^#]+)#[a-zA-Z0-9._-]* $1", # remove fragment from GitHub **main** URLS
1212
# `rewrites` from the `.vitepress/config.mts` file
13-
"([\\w]+)/vectorchord/usage/external-index-precomputation $1/vectorchord/usage/external-build",
14-
"([\\w]+)/vectorchord/usage/range-query $1/vectorchord/usage/similarity-filter",
1513
"([\\w]+)/vectorchord/usage/indexing-with-maxsim-operators $1/vectorchord/usage/multi-vector-retrieval",
14+
"([\\w]+)/vectorchord/usage/range-query $1/vectorchord/usage/similarity-filter",
15+
"([\\w]+)/vectorchord/usage/performance-tuning $1/vectorchord/usage/postgresql-tuning",
16+
"([\\w]+)/vectorchord/usage/external-index-precomputation $1/vectorchord/usage/external-build",
1617
]
18+
exclude = ['^https?://(blog\.|docs\.)pgvecto\.rs/.*$']

src/vectorchord/getting-started/overview.md

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -65,27 +65,21 @@ INSERT INTO items (embedding) SELECT ARRAY[random(), random(), random()]::real[]
6565
With VectorChord, you can create `vchordrq` indexes.
6666

6767
```SQL
68-
CREATE INDEX ON items USING vchordrq (embedding vector_l2_ops) WITH (options = $$
69-
residual_quantization = true
70-
[build.internal]
71-
lists = []
72-
$$);
68+
CREATE INDEX ON items USING vchordrq (embedding vector_l2_ops);
7369
```
7470

7571
And then perform a vector search using `SELECT ... ORDER BY ... LIMIT ...`.
7672

7773
```SQL
78-
SET vchordrq.probes TO '';
7974
SELECT * FROM items ORDER BY embedding <-> '[3,1,2]' LIMIT 5;
8075
```
8176

8277
For more usage, please read:
8378

8479
- [Indexing](/vectorchord/usage/indexing)
85-
- [Search](/vectorchord/usage/search)
8680
- [Multi-Vector Retrieval](/vectorchord/usage/indexing-with-maxsim-operators)
8781
- [Similarity Filter](/vectorchord/usage/range-query)
88-
- [Performance Tuning](/vectorchord/usage/performance-tuning)
82+
- [PostgreSQL Tuning](/vectorchord/usage/performance-tuning)
8983
- [Monitoring](/vectorchord/usage/monitoring)
9084
- [Prewarm](/vectorchord/usage/prewarm)
9185
- [Prefilter](/vectorchord/usage/prefilter)

src/vectorchord/index.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,9 @@
99
## Usage
1010

1111
- [Indexing](/vectorchord/usage/indexing)
12-
- [Search](/vectorchord/usage/search)
1312
- [Multi-Vector Retrieval](/vectorchord/usage/indexing-with-maxsim-operators)
1413
- [Similarity Filter](/vectorchord/usage/range-query)
15-
- [Performance Tuning](/vectorchord/usage/performance-tuning)
14+
- [PostgreSQL Tuning](/vectorchord/usage/performance-tuning)
1615
- [Monitoring](/vectorchord/usage/monitoring)
1716
- [Prewarm](/vectorchord/usage/prewarm)
1817
- [Prefilter](/vectorchord/usage/prefilter)

src/vectorchord/usage/indexing.md

Lines changed: 136 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,25 +5,51 @@ VectorChord's index type `vchordrq` divides vectors into lists and searches only
55
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.
66

77
```sql
8-
CREATE TABLE items (embedding vector(3));
8+
CREATE TABLE items (id bigserial PRIMARY KEY, embedding vector(3));
99
INSERT INTO items (embedding) SELECT ARRAY[random(), random(), random()]::real[] FROM generate_series(1, 1000);
1010
```
1111

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+
CREATE INDEX ON 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]' LIMIT 10;
22+
```
23+
24+
You can also add filters to vector search queries as needed.
25+
26+
```sql
27+
SELECT * FROM items WHERE id % 7 <> 0 ORDER BY embedding <-> '[3,1,2]' LIMIT 10;
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+
CREATE INDEX ON items USING vchordrq (embedding vector_l2_ops);
36+
37+
SELECT * FROM items ORDER BY embedding <-> '[3,1,2]' LIMIT 10;
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.
1341

1442
```sql
1543
CREATE INDEX ON items USING vchordrq (embedding vector_l2_ops) WITH (options = $$
16-
residual_quantization = true
1744
[build.internal]
1845
lists = [1000]
19-
build_threads = 16
2046
$$);
47+
48+
SET vchordrq.probes TO '10';
49+
SELECT * FROM items ORDER BY embedding <-> '[3,1,2]' LIMIT 10;
2150
```
2251

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.
2753

2854
| Number of Rows $N$ | Recommended Number of Partitions $L$ | Example `lists` |
2955
| -------------------------------------- | ------------------------------------ | --------------- |
@@ -32,18 +58,56 @@ $$);
3258
| $N \in [2 \times 10^6, 5 \times 10^7)$ | $L \in [4 \sqrt{N}, 8 \sqrt{N}]$ | `[10000]` |
3359
| $N \in [5 \times 10^7, \infty)$ | $L \in [8 \sqrt{N}, 16\sqrt{N}]$ | `[80000]` |
3460

35-
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.
3662

3763
```sql
38-
SET vchordrq.probes = '10';
39-
SELECT * FROM items ORDER BY embedding <-> '[3,1,2]' LIMIT 5;
64+
CREATE INDEX ON items USING vchordrq (embedding vector_l2_ops) WITH (options = $$
65+
[build.internal]
66+
lists = [1000]
67+
build_threads = 8
68+
$$);
69+
70+
SET vchordrq.probes TO '10';
71+
SELECT * FROM items ORDER BY embedding <-> '[3,1,2]' LIMIT 10;
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+
CREATE INDEX ON 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+
SET vchordrq.probes TO '10';
88+
SELECT * FROM items ORDER BY embedding <=> '[3,1,2]' LIMIT 10;
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+
CREATE INDEX ON items USING vchordrq (embedding vector_l2_ops) WITH (options = $$
97+
residual_quantization = true
98+
build.pin = true
99+
[build.internal]
100+
lists = [1000]
101+
spherical_centroids = true
102+
build_threads = 8
103+
$$);
40104
```
41105

42106
## Reference
43107

44-
### Operator Classes
108+
### Operator Classes <badge type="info" text="vchordrq" /> {#operator-classes}
45109

46-
The table below shows all operator classes for `vchordrq`.
110+
The following table lists all available operator classes supported by `vchordrq`.
47111

48112
| Operator Class | Description | Operator 1 | Operator 2 |
49113
| -------------------- | --------------------------------------------------------------- | ------------------------- | ------------------------ |
@@ -56,15 +120,23 @@ The table below shows all operator classes for `vchordrq`.
56120
| `vector_maxsim_ops` | index works for `vector[]` type and scalable vector-similarity | `@#(vector[],vector[])` | N/A |
57121
| `halfvec_maxsim_ops` | index works for `halfvec[]` type and scalable vector-similarity | `@#(halfvec[],halfvec[])` | N/A |
58122

123+
`<->`, `<#>` and `<=>` are operators defined by pgvector.
124+
125+
| Name | Description |
126+
| ----- | -------------------------- |
127+
| `<->` | squared Euclidean distance |
128+
| `<#>` | negative dot product |
129+
| `<=>` | cosine distance |
130+
59131
`<<->>`, `<<#>>`, `<<=>>` and `@#` are operators defined by VectorChord.
60132

61133
For more information about `<<->>`, `<<#>>`, `<<=>>`, refer to [Similarity Filter](range-query).
62134

63135
For more information about `@#`, refer to [Multi-Vector Retrieval](indexing-with-maxsim-operators).
64136

65-
The operator classes for `MaxSim` have been available only since version `0.3.0`.
137+
The operator classes for `MaxSim` are available since version `0.3.0`.
66138

67-
### Indexing Options
139+
### Indexing Options <badge type="info" text="vchordrq" /> {#indexing-options}
68140

69141
#### `residual_quantization`
70142

@@ -75,7 +147,16 @@ The operator classes for `MaxSim` have been available only since version `0.3.0`
75147
- `residual_quantization = false` means that residual quantization is not used.
76148
- `residual_quantization = true` means that residual quantization is used.
77149

78-
### Internal Build Options
150+
#### `build.pin` <badge type="tip" text="since v0.2.1" />
151+
152+
- 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.
158+
159+
### Internal Build Options <badge type="info" text="vchordrq" />
79160

80161
#### `build.internal.lists`
81162

@@ -88,7 +169,7 @@ The operator classes for `MaxSim` have been available only since version `0.3.0`
88169
- `build.internal.lists = []` means that the vector space is not partitioned.
89170
- `build.internal.lists = [4096]` means the vector space is divided into $4096$ cells.
90171
- `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.
92173

93174
#### `build.internal.spherical_centroids`
94175

@@ -120,7 +201,7 @@ The operator classes for `MaxSim` have been available only since version `0.3.0`
120201
- `build.internal.kmeans_iterations = 10` means that the K-means algorithm performs $10$ iterations.
121202
- `build.internal.kmeans_iterations = 100` means that the K-means algorithm performs $100$ iterations.
122203

123-
#### `build.internal.build_threads` {#build-internal-build-threads}
204+
#### `build.internal.build_threads`
124205

125206
- 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.
126207
- Type: integer
@@ -129,3 +210,40 @@ The operator classes for `MaxSim` have been available only since version `0.3.0`
129210
- Example:
130211
- `build.internal.build_threads = 1` means that the K-means algorithm uses $1$ thread.
131212
- `build.internal.build_threads = 4` means that the K-means algorithm uses $4$ threads.
213+
214+
### Search Parameters <badge type="info" text="vchordrq" />
215+
216+
#### `vchordrq.probes`
217+
218+
- 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+
- ` ` <badge type="tip" text="since v0.3.0" />
222+
- `10` <badge type="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` <badge type="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

Comments
 (0)