Skip to content

Commit 28bcf1c

Browse files
authored
update readme and comparison with pgvector (#63)
* update readme and comparison with pgvector Signed-off-by: Jinjing.Zhou <allenzhou@tensorchord.ai> * add Signed-off-by: Jinjing.Zhou <allenzhou@tensorchord.ai> * comparison Signed-off-by: Jinjing.Zhou <allenzhou@tensorchord.ai> * address comment Signed-off-by: Jinjing.Zhou <allenzhou@tensorchord.ai> * fix Signed-off-by: Jinjing.Zhou <allenzhou@tensorchord.ai> --------- Signed-off-by: Jinjing.Zhou <allenzhou@tensorchord.ai>
1 parent 94c9e9b commit 28bcf1c

6 files changed

+216
-127
lines changed

README.md

+45-127
Original file line numberDiff line numberDiff line change
@@ -16,101 +16,35 @@ pgvecto.rs is a Postgres extension that provides vector similarity search functi
1616
- 🥅 **Filtering**: pgvecto.rs supports filtering. You can set conditions when searching or retrieving points. This is the missing feature of other postgres extensions.
1717
- 🚀 **High Performance**: pgvecto.rs is designed to provide significant improvements compared to existing Postgres extensions. Benchmarks have shown that its HNSW index can deliver search performance up to 20 times faster than other indexes like ivfflat.
1818
- 🔧 **Extensible**: pgvecto.rs is designed to be extensible. It is easy to add new index structures and search algorithms. This flexibility ensures that pgvecto.rs can adapt to emerging vector search algorithms and meet diverse performance needs.
19-
- 🦀 **Rewrite in Rust**: Rust's strict compile-time checks ensure memory safety, reducing the risk of bugs and security issues commonly associated with C extensions.
19+
- 🦀 **Rewrite in Rust**: Rust's strict compile-time checks ensure memory safety, reducing the risk of bugs and security issues commonly associated with C extensions.
2020
- 🙋 **Community Driven**: We encourage community involvement and contributions, fostering innovation and continuous improvement.
2121

22-
## Installation
23-
24-
### Try with docker
25-
26-
We have prebuild image at [tensorchord/pgvecto-rs](https://hub.docker.com/r/tensorchord/pgvecto-rs). You can try it with
27-
28-
```
29-
docker run --name pgvecto-rs-demo -e POSTGRES_PASSWORD=mysecretpassword -p 5432:5432 -d tensorchord/pgvecto-rs:latest
30-
```
31-
32-
To acheive full performance, please mount the volume to pg data directory by adding the option like `-v $PWD/pgdata:/var/lib/postgresql/data`
33-
34-
Reference: https://hub.docker.com/_/postgres/.
35-
36-
<details>
37-
<summary>Build from source</summary>
38-
39-
### Install Rust and base dependency
40-
41-
```sh
42-
sudo apt install -y build-essential libpq-dev libssl-dev pkg-config gcc libreadline-dev flex bison libxml2-dev libxslt-dev libxml2-utils xsltproc zlib1g-dev ccache clang git
43-
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
44-
```
45-
46-
### Clone the Repository
47-
48-
```sh
49-
git clone https://github.com/tensorchord/pgvecto.rs.git
50-
cd pgvecto.rs
51-
```
52-
53-
### Install Postgresql and pgrx
54-
55-
```sh
56-
sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'
57-
wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -
58-
sudo apt-get update
59-
sudo apt-get -y install libpq-dev postgresql-15 postgresql-server-dev-15
60-
cargo install cargo-pgrx --git https://github.com/tensorchord/pgrx.git --rev $(cat Cargo.toml | grep "pgrx =" | awk -F'rev = "' '{print $2}' | cut -d'"' -f1)
61-
cargo pgrx init --pg15=/usr/lib/postgresql/15/bin/pg_config
62-
```
63-
64-
### Install pgvecto.rs
65-
66-
```sh
67-
cargo pgrx install --release
68-
```
69-
70-
Configure your PostgreSQL by modifying the `shared_preload_libraries` to include `vectors.so`.
71-
72-
```sh
73-
psql -U postgres -c 'ALTER SYSTEM SET shared_preload_libraries = "vectors.so"'
74-
```
75-
76-
You need restart the PostgreSQL cluster.
77-
78-
```sh
79-
sudo systemctl restart postgresql.service
80-
```
81-
82-
</details>
83-
84-
<details>
85-
<summary>Install from release</summary>
22+
## Comparison with pgvector
8623

87-
Download the deb package in the release page, and type `sudo apt install vectors-pg15-*.deb` to install the deb package.
24+
| | pgvecto.rs | pgvector |
25+
| ------------------------------------------- | ----------------------------------- | ------------------------- |
26+
| Transaction support || ⚠️ |
27+
| Sufficient Result with Delete/Update/Filter || ⚠️ |
28+
| Vector Dimension Limit | 65535 | 2000 |
29+
| Prefilter on HNSW |||
30+
| Parallel Index build | ⚡️ Linearly faster with more cores | 🐌 Only single core used |
31+
| Index Persistence | mmap file | Postgres internal storage |
32+
| WAL amplification | 2x 😃 | 30x 🧐 |
8833

89-
Configure your PostgreSQL by modifying the `shared_preload_libraries` to include `vectors.so`.
34+
And based on our benchmark, pgvecto.rs can be up to 2x faster than pgvector on hnsw indexes with same configurations. Read more about the comparison at [here](./docs/comparison-pgvector.md).
9035

91-
```sh
92-
psql -U postgres -c 'ALTER SYSTEM SET shared_preload_libraries = "vectors.so"'
93-
```
36+
## Installation
9437

95-
You need restart the PostgreSQL cluster.
38+
We recommend you to try pgvecto.rs using our pre-built docker, by running
9639

97-
```sh
98-
sudo systemctl restart postgresql.service
40+
```bash
41+
docker run --name pgvecto-rs-demo -e POSTGRES_PASSWORD=mysecretpassword -p 5432:5432 -d tensorchord/pgvecto-rs:latest
9942
```
10043

101-
</details>
102-
103-
104-
Connect to the database and enable the extension.
105-
106-
```sql
107-
DROP EXTENSION IF EXISTS vectors;
108-
CREATE EXTENSION vectors;
109-
```
44+
For more installation method (binary install or install from source), read more at [docs/install.md](./docs/install.md)
11045

11146
## Get started
11247

113-
11448
Run the following SQL to ensure the extension is enabled
11549

11650
```sql
@@ -223,6 +157,10 @@ We planning to support more index types ([issue here](https://github.com/tensorc
223157

224158
Welcome to contribute if you are also interested!
225159

160+
## Why not a specialized vector database?
161+
162+
Read our blog at [modelz.ai/blog/pgvector](https://modelz.ai/blog/pgvector)
163+
226164
## Reference
227165

228166
### `vector` type
@@ -237,55 +175,35 @@ There is only one exception: indexes cannot be created on columns without specif
237175

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

240-
| Key | Type | Description |
241-
| ---------------------- | ------- | --------------------------------------------------------------------------------------------------------------------- |
242-
| capacity | integer | The index's capacity. The value should be greater than the number of rows in your table. |
243-
| vectors | table | Configuration of background process vector storage. |
244-
| vectors.memmap | string | (Optional) `ram` ensures that the vectors always stays in memory while `disk` suggests otherwise. |
245-
| algorithm.ivf | table | If this table is set, the IVF algorithm will be used for the index. |
246-
| algorithm.ivf.memmap | string | (Optional) `ram` ensures that the persisent part of algorithm always stays in memory while `disk` suggests otherwise. |
247-
| algorithm.ivf.nlist | integer | Number of cluster units. |
248-
| algorithm.ivf.nprobe | integer | Number of units to query. |
249-
| algorithm.hnsw | table | If this table is set, the HNSW algorithm will be used for the index. |
250-
| algorithm.hnsw.memmap | string | (Optional) `ram` ensures that the persisent part of algorithm always stays in memory while `disk` suggests otherwise. |
251-
| algorithm.hnsw.m | integer | (Optional) Maximum degree of the node. |
252-
| algorithm.hnsw.ef | integer | (Optional) Search scope in building. |
253-
254-
## Limitations
255-
- The index is constructed and persisted using a memory map file (mmap) instead of PostgreSQL's shared buffer. As a result, physical replication or logical replication may not function correctly. Additionally, vector indexes are not automatically loaded when PostgreSQL restarts. To load or unload the index, you can utilize the `vectors_load` and `vectors_unload` commands.
256-
- The filtering process is not yet optimized. To achieve optimal performance, you may need to manually experiment with different strategies. For example, you can try searching without a vector index or implementing post-filtering techniques like the following query: `select * from (select * from items ORDER BY embedding <-> '[3,2,1]' LIMIT 100 ) where category = 1`. This involves using approximate nearest neighbor (ANN) search to obtain enough results and then applying filtering afterwards.
257-
258-
259-
## Why not a specialty vector database?
260-
261-
Imagine this, your existing data is stored in a Postgres database, and you want to use a vector database to do some vector similarity search. You have to move your data from Postgres to the vector database, and you have to maintain two databases at the same time. This is not a good idea.
262-
263-
Why not just use Postgres to do the vector similarity search? This is the reason why we build pgvecto.rs. The user journey is like this:
178+
| Key | Type | Description |
179+
| --------------------- | ------- | --------------------------------------------------------------------------------------------------------------------- |
180+
| capacity | integer | The index's capacity. The value should be greater than the number of rows in your table. |
181+
| vectors | table | Configuration of background process vector storage. |
182+
| vectors.memmap | string | (Optional) `ram` ensures that the vectors always stays in memory while `disk` suggests otherwise. |
183+
| algorithm.ivf | table | If this table is set, the IVF algorithm will be used for the index. |
184+
| algorithm.ivf.memmap | string | (Optional) `ram` ensures that the persisent part of algorithm always stays in memory while `disk` suggests otherwise. |
185+
| algorithm.ivf.nlist | integer | Number of cluster units. |
186+
| algorithm.ivf.nprobe | integer | Number of units to query. |
187+
| algorithm.hnsw | table | If this table is set, the HNSW algorithm will be used for the index. |
188+
| algorithm.hnsw.memmap | string | (Optional) `ram` ensures that the persisent part of algorithm always stays in memory while `disk` suggests otherwise. |
189+
| algorithm.hnsw.m | integer | (Optional) Maximum degree of the node. |
190+
| algorithm.hnsw.ef | integer | (Optional) Search scope in building. |
191+
192+
And you can change the number of expected result (such as `ef_search` in hnsw) by using the following SQL.
264193

265194
```sql
266-
-- Update the embedding column for the documents table
267-
UPDATE documents SET embedding = ai_embedding_vector(content) WHERE length(embedding) = 0;
268-
269-
-- Create an index on the embedding column
270-
CREATE INDEX ON documents USING vectors (embedding l2_ops)
271-
WITH (options = $$
272-
capacity = 2097152
273-
[vectors]
274-
memmap = "ram"
275-
[algorithm.hnsw]
276-
memmap = "ram"
277-
m = 32
278-
ef = 256
279-
$$);
280-
281-
-- Query the similar embeddings
282-
SELECT * FROM documents ORDER BY embedding <-> ai_embedding_vector('hello world') LIMIT 5;
195+
--- (Optional) Expected number of candidates returned by index
196+
SET vectors.k = 32;
197+
--- Or use local to set the value for the current session
198+
SET LOCAL vectors.k = 32;
283199
```
284200

285-
From [SingleStore DB Blog](https://www.singlestore.com/blog/why-your-vector-database-should-not-be-a-vector-database/):
201+
````
286202
287-
> Vectors and vector search are a data type and query processing approach, not a foundation for a new way of processing data. Using a specialty vector database (SVDB) will lead to the usual problems we see (and solve) again and again with our customers who use multiple specialty systems: redundant data, excessive data movement, lack of agreement on data values among distributed components, extra labor expense for specialized skills, extra licensing costs, limited query language power, programmability and extensibility, limited tool integration, and poor data integrity and availability compared with a true DBMS.
203+
## Limitations
288204
205+
- The index is constructed and persisted using a memory map file (mmap) instead of PostgreSQL's shared buffer. As a result, physical replication or logical replication may not function correctly. Additionally, vector indexes are not automatically loaded when PostgreSQL restarts. To load or unload the index, you can utilize the `vectors_load` and `vectors_unload` commands.
206+
- The filtering process is not yet optimized. To achieve optimal performance, you may need to manually experiment with different strategies. For example, you can try searching without a vector index or implementing post-filtering techniques like the following query: `select * from (select * from items ORDER BY embedding <-> '[3,2,1]' LIMIT 100 ) where category = 1`. This involves using approximate nearest neighbor (ANN) search to obtain enough results and then applying filtering afterwards.
289207
290208
## Setting up the development environment
291209
@@ -294,7 +212,7 @@ You could use [envd](https://github.com/tensorchord/envd) to set up the developm
294212
```sh
295213
pip install envd
296214
envd up
297-
```
215+
````
298216

299217
## Contributing
300218

0 commit comments

Comments
 (0)