My previous post has results for MariaDB and pgvector on the dbpedia-openai dataset. This post adds results from Qdrant. This uses ann-benchmarks to compare MariaDB, Qdrant and Postgres (pgvector) with a larger dataset, dbpedia-openai at 500k rows. The dataset has 1536 dimensions and uses angular (cosine) as the distance metric. This work was done by Small Datum LLC and sponsored by the MariaDB Corporation.
tl;dr
- I am new to Qdrant so the chance that I made a mistake are larger than for MariaDB or Postgres
- If you already run MariaDB or Postgres then I suggest you also use them for vector indexes
- MariaDB usually gets ~2X more QPS than pgvector and ~1.5 more than Qdrant
- Production is expensive -- you have to worry about security, backups, operational support
- A new DBMS is expensive -- you have to spend time to learn how to use it
So I decided to try the Docker container they provide. I ended up not changing the Qdrant configuration provided in the Docker container. I spent some time doing performance debugging and didn't see anything to indicate that a config change was needed. For example, I didn't see disk IO during queries. But the performance debugging was harder because that Docker container image doesn't come with my favorite debug tools installed. Some of the tools were easy to install, others (perf) were not.
This post has much more detail about my approach in general. I ran the benchmark for 1 session. I use ann-benchmarks via my fork of a fork of a fork at this commit.
The ann-benchmarks config files are here for MariaDB, Postgres and Qdrant. For Postgres I use the values for M and ef_construction. But MariaDB doesn't support ef_construction so I only specify the M values. While pgvector requires ef_construction to be >= 2*M, I do not know whether Qdrant has a similar requirement. Regardless I only test cases where that constraint is true.
- MariaDB uses 16-bit integers rather than float32
- pgvector uses float32, pgvector halfvec uses float16
- For Qdrant I used none (float32) and scalar (int8)
The command lines to run the benchmark using my helper scripts are:
These charts show the best QPS for a given recall. MariaDB gets more QPS than Qdrant and pgvector but that is harder to see as the recall approaches 1, so the next section has a table for best QPS per DBMS at a given recall.
Results: create index
- index sizes are similar between MariaDB and pgvector with halfvec
- time to create the index varies a lot and it is better to consider this in the context of recall which is done in next section. But Qdrant creates indexes a lot faster than MariaDB or pgvector.
- I did not find an accurate way to determine index size for Qdrant. There is a default method in ann-benchmarks that a DBMS can override. The default just compares process RSS before and after creating an index which isn't accurate for small indexes. The MariaDB and Postgres code override the default and query the data dictionary to get a more accurate estimate.
More details on index size and index create time for MariaDB and Postgres are in my previous post.
With ann-benchmarks the constraint is recall. Below I share the best QPS for a given recall target along with the configuration parameters (M, ef_construction, ef_search) at which that occurs for each of the algorithms -- MariaDB, pgvector with float32 and float16/halfvec, Qdrant with no and scalar quantization.
- Qdrant with scalar quantization does not get a result for recall=1.0 for the values of M, ef_construction and ef_search I used
- MariaDB usually gets ~2X more QPS than pgvector and ~1.5 more than Qdrant
- Index create time was much less for Qdrant (described above)
- recall, QPS - best QPS at that recall
- rel2ma - (QPS for me / QPS for MariaDB)
- m= is the value for M when creating the index
- ef_cons= is the value for ef_construction when creating the index
- ef_search= is the value for ef_search when running queries
- quant= is the quantization used by Qdrant
- dbms
- MariaDB - MariaDB, there is no option for quantization
- PGVector - Postgres with pgvector and float32
- PGVector_halfvec - Postgres with pgvector and halfvec (float16)
- Qdrant(..., quant=none) - Qdrant with no quantization
- Qdrant(..., quant=scalar) - Qdrant with scalar quantization
No comments:
Post a Comment