Comments (9)
@ankane @pashkinelfe Your suggestions were very helpful.
This is the result of using 'pg_prewarm'. In the results below, the top 2 were using 'pg_prewarm' to warm up the indexes. It didn't take long.
Average QPS: 110.34824108994871, Total Queries Processed: 1079
Average QPS: 107.39188954299956, Total Queries Processed: 1112
Average QPS: 5.389447228919696, Total Queries Processed: 54
Average QPS: 16.25110630066733, Total Queries Processed: 155
Average QPS: 5.931909562061934, Total Queries Processed: 60
Average QPS: 6.5119287118480065, Total Queries Processed: 63
Average QPS: 6.479642628293995, Total Queries Processed: 67
Average QPS: 6.736313818006796, Total Queries Processed: 70
To summarize, I can say that using 'pg_prewarm' has performed the best in my case so far. Of course, in my case, especially since I have a very large index size (400 GB for the vector indexes of all tables combined), I think it will require a very large memory. Nevertheless, I think it should be possible to achieve faster TPS than what I have now, because I have seen very fast QPS results in blog posts, including supabase. Other control variables such as vector length, postgresql configuration, etc. remain to be seen.
from pgvector.
It looks like the buffer hit rate is pretty low, so a lot of reads are happening from disk. I suspect you'll see better performance with an SSD, especially since HNSW does a lot of random access. I don't think partitioning will help in this situation (unless you're filtering by the partition key). You could also try prewarming the index with pg_prewarm
to get it in memory, but it may not stay there.
from pgvector.
I measured QPS with just moving the database to SSD (each line is a different table, with more data stored as you go down. The top row has 10 million rows and the last row has 20 million rows, with more rows as you go down):
Average QPS: 7.245211969821667, Total Queries Processed: 8
Average QPS: 6.831864681418859, Total Queries Processed: 7
Average QPS: 77.75631549154483, Total Queries Processed: 76
Average QPS: 78.14635672947067, Total Queries Processed: 99
Average QPS: 6.005239444042287, Total Queries Processed: 7
Average QPS: 5.587675697528546, Total Queries Processed: 7
Average QPS: 5.5092620964731545, Total Queries Processed: 6
Average QPS: 5.468562478180391, Total Queries Processed: 6
And this is the output of explain (analyze, buffers)
for one of the queries:
Table that had slow QPS.
Limit (cost=224.84..226.83 rows=3 width=1261) (actual time=163.940..164.732 rows=3 loops=1)
Buffers: shared hit=473 read=1186
-> Index Scan using paper_2016_embedding_idx on paper_2016 (cost=224.84..3815999.63 rows=5742623 width=1261) (actual time=163.937..164.727 rows=3 loops=1)
Order By: (embedding <=> '[0.6871753,-0.11484199,-0.52307606,...]'::vector)
Buffers: shared hit=473 read=1186
Planning:
Buffers: shared hit=1
Planning Time: 0.153 ms
Execution Time: 164.778 ms
Table that had fast QPS.
Limit (cost=224.84..226.81 rows=3 width=1245) (actual time=15.788..16.005 rows=3 loops=1)
Buffers: shared hit=1210 read=29
-> Index Scan using paper_2018_embedding_idx on paper_2018 (cost=224.84..5054610.74 rows=7706712 width=1245) (actual time=15.784..15.998 rows=3 loops=1)
Order By: (embedding <=> '[0.6871753,-0.11484199,-0.52307606,...]'::vector)
Buffers: shared hit=1210 read=29
Planning:
Buffers: shared hit=42 read=10
Planning Time: 1.375 ms
Execution Time: 16.055 ms
Things are much better than before. But It looks like only the fastest tables are in the buffer. There is still a 'pg_prewarm' task left. However, in my case, my largest table is 100G excluding indexes(80G), so I don't expect it to work well. But I will give it a try.
from pgvector.
Great, thanks for sharing @williamjeong2!
from pgvector.
Hi @williamjeong2, can you paste the output of EXPLAIN (ANALYZE, BUFFERS)
for one of the queries?
from pgvector.
Hi @ankane, here is the output(768 dim):
Limit (cost=224.84..226.81 rows=3 width=1247) (actual time=8249.103..8318.815 rows=3 loops=1)
Buffers: shared hit=128 read=1246
-> Index Scan using paper_embedding_idx on paper (cost=224.84..11281870.44 rows=17203648 width=1247) (actual time=8249.099..8318.807 rows=3 loops=1)
Order By: (embedding <=> '[0.8093864,0.60382533,...]'::vector)
Buffers: shared hit=128 read=1246
Planning:
Buffers: shared hit=118
Planning Time: 2.416 ms
Execution Time: 8319.119 ms
from pgvector.
@ankane
Thanks so much, I'll try the things you suggested to me and share them here for use cases.
from pgvector.
Awesome, sounds good.
from pgvector.
@williamjeong2 Considering you have 20Gb HNSW index, it is likely that pg_prewarm will help. Otherwise 'natural' warm-up could take a long time. To check, try running your test for around 1000 sec and see how TPS evolves. Or just use pg_prewarm )
from pgvector.
Related Issues (20)
- What are the impacts of dimension for sparsevec? HOT 1
- Duplicate error when creating a vector index using HNSW HOT 6
- tuning the tmpCtx to improve HNSW build performance HOT 5
- Index vector_ip_ops does not work for halfvec HOT 1
- Can the "LIMIT" statement be included as one of arguments when doing scan operation? HOT 1
- SQL Error [XX000]: FATAL: failed to open bitcode file "/usr/local/lib/postgresql/bitcode/vector/src/vector.bc": No such file or directory HOT 4
- how to list existing databases in postgresql using python HOT 2
- HNSW Indexing and Filtering HOT 2
- A question about building index in background. HOT 1
- Installation instructions unclear HOT 1
- Large vector data type will cause performance decline? HOT 1
- A question regard table_open() in background worker when building index HOT 3
- jVector Implementation
- Type Error when working with Langchain (Missing Positional Argument: evalue) HOT 1
- pgvector still use row-based storage instead of columnar storage ? HOT 1
- Can't get the query planner to use HNSW index HOT 3
- 【search failed】 2000w、768dim, data search failed HOT 1
- ERROR: index row size 6160 exceeds btree version 4 maximum 2704 for index HOT 3
- Make difficulties HOT 2
- Table Insert Performance with HNSW Index HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from pgvector.