from mqp on Discord

pgvector isn't as weird as it looks, i suggest just understanding it, it took me about half an hour of reading and thinking about the papers etc. it points to. the short version is

  1. when you make the index it uses some kind of k-means clustering sort of algorithm to partition all the existing data points into K spatial clusters. iirc K = the lists parameter to the index
  2. it never changes these clusters. data points are assigned to the clusters when you insert/update/delete
  3. when you do a query of the form select order by distance to point limit N it tries to figure out whether it should use the index based on normal stuff like how large N is compared to the table size

so if you understand this then you understand

  1. if it decides it should use the index, then it will determine N clusters to look at, N = the probes pgvector config, it will pick the N clusters with the closest centroids to the point you are looking for close rows to
  2. then it will look for points in those clusters only for your query, speeding up your query by a factor of ~N/K compared to if it scanned all points

Actionable bits

-- This index has a small number of lists and resulted in the planner 
-- ignoring my index using the query from below
create index concurrently if not exists user_embeddings_interest_embedding_2 on user_embeddings using ivfflat (interest_embedding vector_cosine_ops)
    with (lists = 100);
-- this index has a larger number of lists and the planner used my index
create index concurrently if not exists user_embeddings_interest_embedding_2 on user_embeddings using ivfflat (interest_embedding vector_cosine_ops)
    with (lists = 500);

Another person’s experience with changing their lists parameter:

Untitled