This page provides a detailed reference for the tuning parameters available for Scalable Nearest Neighbors (ScaNN) indexes in AlloyDB for PostgreSQL.
For a step-by-step tutorial on how to implement vector search from start to finish, see the guide on how to Perform a vector search .
Tuning parameters
The following index and query parameters are used to find the right balance of recall and queries per second (QPS).
max_num_levels
- Two-level tree index: Set to
1by default for a two-level tree (1 centroid level + bottom leaf level). - Three-level tree index: Set to
2by default for a three-level tree (2 centroid levels + bottom leaf level) - Set the value to
2if the number of vector rows exceeds 100 million rows. - Set the value to
1if the number of vector rows are less than 10 million rows. - Set to either
1or2if the number of vector rows lie between 10 million and 100 million rows to optimize for index build time (set to 2) or optimize for search recall (set to 1).
(optional)
num_leaves
Since three-level trees build faster than two-level trees, you can increase the
num_leaves_value
when creating a three-level tree index to achieve better performance.- Two-level index: Set this value to any value between
1and1048576.
For an index that balances fast index build and good search performance, usesqrt(ROWS)as a starting point, whereROWSis the number of vector rows. The number of vectors that each partition holds is calculated by
ROWS/sqrt(ROWS) = sqrt(ROWS).
Since a two-level tree index can be created on a dataset with less than 10 million vector rows, each partition will hold less than (sqrt(10M)) vectors, which is3200vectors. For optimal vector search quality, it's recommended to minimize the number of vectors in each partition. The recommended partition size is about 100 vectors per partition, so setnum_leavestoROWS/100. If you have 10 million vectors you would setnum_leavesto 100,000. - Three-level index: Set this value to any value between
1and1048576.
If you are unsure about selecting the exact value, usepower(ROWS, 2/3)as a starting point, whereROWSis the number of vector rows. The number of vectors that each partition holds is calculated by
ROWS/power(ROWS, 2/3) = power(ROWS, 1/3).
Since a three-level tree index can be created on a dataset with vector rows more than 100 million, each partition will hold more than
(power(100M, 1/3)) vectors, which is465vectors. For optimal performance, it's recommended to minimize the number of vectors in each partition. The recommended partition size is about 100 vectors per partition, so setnum_leavestoROWS/100. If you have 100 million vectors you would setnum_leavesto 1 million.
(required)
quantizer
SQ8
which provides better query performance with minimal recall loss (typically less than 1-2%).Set it to
FLAT
if a recall of 99% or higher is required.(optional)
scann.enable_pca
Set to
false
if you observe deterioration in recall.(optional)
auto_maintenance ( Preview
)
auto_maintenance=on
in the WITH
clause when creating an index to enable this feature for manually tuned indexes.For automatically tuned ScaNN indexes, automatic index maintenance is enabled by default. To use automatically tuned indexes, you must set
alloydb.enable_preview_features
to on
.(optional)
scann.pct_leaves_to_search ( Preview
)
1
.You can set this parameter to any value between
0
to 100
. The default value is 0
, which disables this parameter and uses the scann.num_leaves_to_search
to calculate the number of leaves to search. The parameter is disabled by default.scann.num_leaves_to_search
num_leaves
.A higher value will result in better recall but lower QPS. Similarly, a lower value will result in lower recall but higher QPS.
(optional)
scann.pre_reordering_num_neighbors
A higher value results in better recall, but a lower QPS. Set this value to
0
to disable reordering. The default is 0
if PCA is not enabled during index creation. Otherwise, the default is 50 x K
, where K
is the LIMIT specified in the query.(optional)
scann.num_search_threads
2
.(optional)
scann.satisfy_limit
( Preview
)
relaxed_order
, the database flag addresses insufficient recall. Insufficient recall can occur when a query's observed recall falls below the target recall, which is more likely when using filters. This setting helps achieve the target recall by allowing the vector scan to continue searching beyond the num_leaves_to_search
limit until a sufficient number of results are found.(optional)
scann.max_pct_leaves_to_search
( Preview
)
scann.satisfy_limit
enabled. This is the only upper bound GUC available and applies to both auto and manual search modes. It prevents the search from overshooting, which might significantly degrade performance. This is applicable when scann.satisfy_limit
is turned on.You can set this parameter to any value between
0
to 100
. The default value is 15%
. This default value is based on the rationale that if a search needs to examine more than 15% of the leaves, the filter is likely selective enough that approximate nearest neighbor (ANN) search doesn't provide a benefit, making pre-filtering k-nearest neighbor (KNN) a more suitable choice.(optional)

