pgvector / pgvector

Open-source vector similarity search for Postgres

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

HNSW index is not used on 0.5.1

nwatab opened this issue · comments

Hi. I run an AWS Aurora PostgreSQL (16.1) and use pgvector 0.5.1 on db.t3.large. They are the latest versions available on AWS RDS Aurora at the moment. I created an HNSW index for my table, but the index is not used. The number of rows are mostly small, but one user has 204k rows as shown in actual. Does any one has some crew?

  • I replaced some uuid and version for better anonymity.
postgres=> EXPLAIN ANALYSE SELECT id FROM vector_table WHERE app_id='{some uuid}' AND version='{some int}' ORDER BY (SELECT embedding FROM vector_table LIMIT 1) <#> embedding LIMIT 30;

 Limit  (cost=137.61..137.65 rows=16 width=24) (actual time=3622.023..3622.031 rows=30 loops=1)
   InitPlan 1 (returns $0)
     ->  Limit  (cost=0.00..0.22 rows=1 width=32) (actual time=0.009..0.010 rows=1 loops=1)
           ->  Seq Scan on vector_table vector_table_1  (cost=0.00..139368.03 rows=642703 width=32) (actual time=0.008..0.008 rows=1 loops=1)
   ->  Sort  (cost=137.39..137.43 rows=16 width=24) (actual time=3622.022..3622.027 rows=30 loops=1)
         Sort Key: (($0 <#> vector_table.embedding))
         Sort Method: top-N heapsort  Memory: 28kB
         ->  Bitmap Heap Scan on vector_table  (cost=73.32..137.07 rows=16 width=24) (actual time=27.909..3567.635 rows=203929 loops=1)
               Recheck Cond: ((version = '{some int}'::smallint) AND (app_id = '{some uuid}'::uuid))
               Heap Blocks: exact=22295
               ->  BitmapAnd  (cost=73.32..73.32 rows=16 width=0) (actual time=23.361..23.363 rows=0 loops=1)
                     ->  Bitmap Index Scan on vector_table_version_idx  (cost=0.00..36.53 rows=3214 width=0) (actual time=12.398..12.398 rows=203929 loops=1)
                           Index Cond: (version = '{some int}'::smallint)
                     ->  Bitmap Index Scan on vector_table_app_id_idx  (cost=0.00..36.53 rows=3214 width=0) (actual time=9.992..9.993 rows=203929 loops=1)
                           Index Cond: (app_id = '{some uuid}'::uuid)
 Planning Time: 0.135 ms
 Execution Time: 3622.240 ms
(17 rows)
postgres=> \d vector_table;
                      Table "public.vector_table"
   Column      |          Type           | Collation | Nullable |      Default       
------------+-------------------------+-----------+----------+--------------------
 id                  | uuid                    |              | not null      | uuid_generate_v4()
 version         | smallint              |              |                   | 
 embedding  | vector(1536)      |             |                    | 
 app_id          | uuid                    |             |                    | 
Indexes:
    "vector_table_pkey" PRIMARY KEY, btree (id)
    "vector_table_app_id_idx" btree (app_id)
    "vector_table_embedding_idx1" hnsw (embedding vector_ip_ops)
    "vector_table_version_idx" btree (version)

Hi @nwatab, it looks like the other indexes are better for the query (as they narrow it down to 30 rows).

Edit: Actually, it looks like there's a large discrepancy between the estimated and actual rows. Try running ANALYZE vector_table or using extended statistics to fix it.

Hi @ankane , thank you for the prompt response. ANALYZE vector_table solved. Thank you so much! Now, it works 1000x faster as shown below.

   ->  Index Scan using vector_table_embedding_idx1 on vector_table  (cost=276.72..1530249.57 rows=61878 width=24) (actual time=3.107..3.754 rows=30 loops=1)
...
 Planning Time: 0.166 ms
 Execution Time: 3.821 ms
(10 rows)