The current command prevents the usage of an index optimized for vector search in postgres. As someone mentioned the Issue is that postgres only supports ASC order index scans. I'm not sure if this is true as I can't find any documentation and I'm everything but a postgres expert. But changing the command to the second one provided made postgres to use the created index. The performance difference is huge from 30s down to 41ms for a database with 134'000 records and 1.2G in Size (with index 2.4G).
Important: Running both queries without the index do provide the same results thats why I'm confident that my adjustment is correct. The difference after creating the index is the result of the trade off between recall and performance which is intended to happen.
Any chance that an expert can look into that? Maybe the conclusion is that we then have to use our own custom postgres client implementation but if my adjustments are correct (similarity only should be inverted) it would be a huge improvement if it can be provided out of the box.
Source:
cmd.CommandText = @$"
SELECT * FROM (SELECT {queryColumns}, 1 - (embedding <=> @embedding) AS cosine_similarity FROM {this.GetFullTableName(tableName)}
) AS sk_memory_cosine_similarity_table
WHERE cosine_similarity >= @min_relevance_score
ORDER BY cosine_similarity DESC
Limit @limit";
Get the query plan used by postgres for the source query:
EXPLAIN (ANALYZE, VERBOSE, BUFFERS) SELECT * FROM
(SELECT key, metadata, timestamp, 1 - (embedding <=> '[]') AS cosine_similarity
FROM public."bger-gpt-3-5-turbo-v1"
) AS sk_memory_cosine_similarity_table
WHERE cosine_similarity >= 0.7
ORDER BY cosine_similarity DESC
limit 5;
CREATE INDEX ON public."bger-gpt-3-5-turbo-v1" USING ivfflat ("embedding" vector_cosine_ops)
WITH (lists = 134);
To Reproduce
Steps to reproduce the behavior:
Create a sample database with at least 1000 - 100'000 dummy records (ivfflat only works when dataset is large enough)
Do a memory recall => Query embedding
Wait 30s
Create a ivfflat index like above for the corresponding vector operation (similarity in this case)
Do a memory recall => Query embedding
Wait again 30s
Check plans using EXPLAIN => Recognize that index is not used
Adjust the query as provided above (second one)
Do a memory recall =>Query embedding
Wait 40ms
Check plans using EXPLAIN => See that the index now is used
Drop the index
Do a memory recall with the adjusted query as provided above => Query embedding
Wait 30s
Check plans using EXPLAIN => See that the Seq. Scan. is the issue as after dropping the index the adjusted query takes now the same amount of time as the one in the source
Expected behavior
Either a hint in the documentation that the query has to be tweeked to the needs or a default implementation that can make use of ivfflat index.
Additional context
I've have removed the vector as it would just clutter the whole description. If access is required hit me up in a PM and I try my best to provide access to the database in question.
Describe the bug
The current command prevents the usage of an index optimized for vector search in postgres. As someone mentioned the Issue is that postgres only supports ASC order index scans. I'm not sure if this is true as I can't find any documentation and I'm everything but a postgres expert. But changing the command to the second one provided made postgres to use the created index. The performance difference is huge from 30s down to 41ms for a database with 134'000 records and 1.2G in Size (with index 2.4G).
Important: Running both queries without the index do provide the same results thats why I'm confident that my adjustment is correct. The difference after creating the index is the result of the trade off between recall and performance which is intended to happen.
Any chance that an expert can look into that? Maybe the conclusion is that we then have to use our own custom postgres client implementation but if my adjustments are correct (similarity only should be inverted) it would be a huge improvement if it can be provided out of the box.
Source:
Get the query plan used by postgres for the source query:
Query plan for the source query (uses Seq. Scan):
Adjustment:
Adjustment Query-Plan in Postgres using index:
Query plan for the adjustmend (using the index):
Index used:
To Reproduce Steps to reproduce the behavior:
Expected behavior Either a hint in the documentation that the query has to be tweeked to the needs or a default implementation that can make use of ivfflat index.
Platform
Additional context I've have removed the vector as it would just clutter the whole description. If access is required hit me up in a PM and I try my best to provide access to the database in question.