Indexes
Indexes are tools for optimizing query performance of a collection.
Collections can be queried without an index, but that will emit a python warning and should never be done in production.
_10query does not have a covering index for cosine_similarity. See Collection.create_index
As each query vector must be checked against every record in the collection. When the number of dimensions and/or number of records becomes large, that becomes extremely slow and computationally expensive.
An index is a heuristic data structure that pre-computes distances between key points in the vector space. It is smaller and can be traversed more quickly than the whole collection enabling much more performant searching.
Only one index may exist per-collection. An index optimizes a collection for searching according to a selected distance measure.
To create an index:
_10docs.create_index()
You may optionally provide a distance measure and index method.
Available options for distance measure
are:
vecs.IndexMeasure.cosine_distance
vecs.IndexMeasure.l2_distance
vecs.IndexMeasure.l1_distance
vecs.IndexMeasure.max_inner_product
which correspond to different methods for comparing query vectors to the vectors in the database.
If you aren't sure which to use, the default of cosine_distance is the most widely compatible with off-the-shelf embedding methods.
Available options for index method
are:
vecs.IndexMethod.auto
vecs.IndexMethod.hnsw
vecs.IndexMethod.ivfflat
Where auto
selects the best available index method, hnsw
uses the HNSW method and ivfflat
uses IVFFlat.
HNSW and IVFFlat indexes both allow for parameterization to control the speed/accuracy tradeoff. vecs provides sane defaults for these parameters. For a greater level of control you can optionally pass an instance of vecs.IndexArgsIVFFlat
or vecs.IndexArgsHNSW
to create_index
's index_arguments
argument. Descriptions of the impact for each parameter are available in the pgvector docs.
When using IVFFlat indexes, the index must be created after the collection has been populated with records. Building an IVFFlat index on an empty collection will result in significantly reduced recall. You can continue upserting new documents after the index has been created, but should rebuild the index if the size of the collection more than doubles since the last index operation.
HNSW indexes can be created immediately after the collection without populating records.
To manually specify method
, measure
, and index_arguments
add them as arguments to create_index
for example:
_10docs.create_index(_10 method=IndexMethod.hnsw,_10 measure=IndexMeasure.cosine_distance,_10 index_arguments=IndexArgsHNSW(m=8),_10)
The time required to create an index grows with the number of records and size of vectors. For a few thousand records expect sub-minute a response in under a minute. It may take a few minutes for larger collections.