postgres-pgvector doesn't use the vector index
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 5.2k
- Forks
- 1.8k
- Avg merge
- 3d 12h
- Merged PRs (30d)
- 6
Description
I built a project on top of the postgres-pgvector template, but the database queries were really slow. I had 2.8 million rows in the database with 512 dimensional embedding vectors. Queries took like 12 seconds. (After using an ivfflat index it took 100ms)
Reproduction repo is here: https://github.com/martinloretzzz/nextjs-drizzle-pgvector
After investigating the issue, it turns out the queries don't use the vector index, because we're looking for the 1 - cosineDistance, while the index is built for the cosine distance only.
The fix is quite simple, need to look for the smallest cosineDistance, instead of the largest 1-cosineDistance:
const similarity = sql<number>`${cosineDistance(pokemons.embedding, vectorQuery)}`
const pokemon = await db
.select({ id: pokemons.id, name: pokemons.name, similarity })
.from(pokemons)
.where(lt(similarity, 0.5))
.orderBy((t) => asc(t.similarity))
.limit(8)
Note:
Use postgres EXPLAIN to see the query plan.
For this small dataset of 150 pokemons, for both queries the index aren't used, to test if index would be used on big datasets, so set SET SESSION enable_seqscan=false;
Exported sql queries: before, after, use with SET SESSION enable_seqscan=false; EXPLAIN {query} is psql/pgadmin
I'll do a PR for this repo later.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the postgres-pgvector example and the reproduction repository linked in the issue. Compare the exported sql-dragon-before.txt and sql-dragon-after.txt queries, then run them with SET SESSION enable_seqscan=false; EXPLAIN. Done means the example's vector query produces the intended plan and preserves the expected result ordering.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- nextjs, postgres, typescript
- Domain
- backend, databases
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 43/100