forked from facebook/mysql-5.6
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[vector] Add support for nprobe session variable and query level hint
Summary: Nearest neighbor search is most accurate with "flat" indexes. With large # of vector embeddings in the dataset, this search can get slow. To speed up the search, approximate nearest neighbor search can be done via indexes like the IVF (family of) indexes. Search accuracy with IVF can be controlled using the "nprobe" value. A higher value of "nprobe" will (possibly) increase the accuracy and a lower value will speed up the query, but may possibly lower the accuracy. The results can be very dataset and usecase-dependent. This diff adds support for defining a default "nprobe" value using a new session variable "rocksdb_nprobe", as well as a new query hint. The query hint can be used to essentially override the default "nprobe" session value. Valid values for both are between 1 and 10000. set session fb_vector_search_nprobe = 10; Query overrides the session default: select /*+ SET_VAR(fb_vector_search_nprobe = 1) */ *, fb_vector_l2(vector1, '[0.3, 0.3]') as dis from t1 force index(key1) order by dis limit 10; Differential Revision: D54886377 fbshipit-source-id: 6acfa2e
- Loading branch information
Showing
10 changed files
with
584 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
234 changes: 234 additions & 0 deletions
234
mysql-test/suite/fb_vectordb/r/ivf_vector_index_nprobe.result
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,234 @@ | ||
insert into VECTORDB_DATA values ('id1', 'metadata', 0, JSON_OBJECT('version', 1)), ('id1', 'quantizer', 0, '[0, 0, 0, 0]'), ('id1', 'quantizer', 1, '[1, 1, 0, 0]'), | ||
('id1', 'quantizer', 2, '[2, 2, 0, 0]'), ('id1', 'quantizer', 3, '[3, 3, 0, 0]'), ('id1', 'quantizer', 4, '[4, 4, 0, 0]'), ('id1', 'quantizer', 5, '[5, 5, 0, 0]'), | ||
('id1', 'quantizer', 6, '[6, 6, 0, 0]'), ('id1', 'quantizer', 7, '[7, 7, 0, 0]'), ('id1', 'quantizer', 8, '[8, 8, 0, 0]'), ('id1', 'quantizer', 9, '[9, 9, 0, 0]'); | ||
CREATE TABLE t1 ( | ||
id BIGINT NOT NULL PRIMARY KEY, | ||
vector1 JSON, | ||
name varchar(64), | ||
INDEX key1(vector1) FB_VECTOR_INDEX_TYPE 'ivfflat' fb_vector_dimension 4 FB_VECTOR_TRAINED_INDEX_TABLE 'VECTORDB_DATA' FB_VECTOR_TRAINED_INDEX_ID 'id1' | ||
); | ||
insert into t1 (WITH RECURSIVE a(i) AS (SELECT 0 union all select i+1 from a where i < 4) SELECT i, json_array(i*0.0001, i*0.0001), concat('val', i) from a); | ||
insert into t1 (WITH RECURSIVE a(i) AS (SELECT 0 union all select i+1 from a where i < 4) SELECT i+1000, json_array(1+i*0.0001, 1-i*0.0001), concat('val', i+1000) from a); | ||
insert into t1 (WITH RECURSIVE a(i) AS (SELECT 0 union all select i+1 from a where i < 4) SELECT i+2000, json_array(2+i*0.0001, 2-i*0.0001), concat('val', i+2000) from a); | ||
insert into t1 (WITH RECURSIVE a(i) AS (SELECT 0 union all select i+1 from a where i < 4) SELECT i+3000, json_array(3+i*0.0001, 3-i*0.0001), concat('val', i+3000) from a); | ||
insert into t1 (WITH RECURSIVE a(i) AS (SELECT 0 union all select i+1 from a where i < 4) SELECT i+4000, json_array(4+i*0.0001, 4-i*0.0001), concat('val', i+4000) from a); | ||
insert into t1 (WITH RECURSIVE a(i) AS (SELECT 0 union all select i+1 from a where i < 4) SELECT i+5000, json_array(5+i*0.0001, 5-i*0.0001), concat('val', i+5000) from a); | ||
insert into t1 (WITH RECURSIVE a(i) AS (SELECT 0 union all select i+1 from a where i < 4) SELECT i+6000, json_array(6+i*0.0001, 6-i*0.0001), concat('val', i+6000) from a); | ||
insert into t1 (WITH RECURSIVE a(i) AS (SELECT 0 union all select i+1 from a where i < 4) SELECT i+7000, json_array(7+i*0.0001, 7-i*0.0001), concat('val', i+7000) from a); | ||
insert into t1 (WITH RECURSIVE a(i) AS (SELECT 0 union all select i+1 from a where i < 4) SELECT i+8000, json_array(8+i*0.0001, 8-i*0.0001), concat('val', i+8000) from a); | ||
insert into t1 (WITH RECURSIVE a(i) AS (SELECT 0 union all select i+1 from a where i < 4) SELECT i+9000, json_array(9+i*0.0001, 9-i*0.0001), concat('val', i+9000) from a); | ||
Check the default value of nprobe | ||
show variables like 'fb_vector_search_nprobe'; | ||
Variable_name Value | ||
fb_vector_search_nprobe 16 | ||
|
||
the following select will end up including all available centroids due to the default nprobe value | ||
with search as (select *, fb_vector_l2(vector1, '[0.3, 0.3]') as dis from t1 force index(key1) order by dis limit 100) select COUNT(*) from search; | ||
COUNT(*) | ||
50 | ||
SELECT NTOTAL, HIT, MIN_LIST_SIZE, MAX_LIST_SIZE, AVG_LIST_SIZE FROM INFORMATION_SCHEMA.ROCKSDB_VECTOR_INDEX WHERE TABLE_NAME = 't1'; | ||
NTOTAL HIT MIN_LIST_SIZE MAX_LIST_SIZE AVG_LIST_SIZE | ||
50 1 5 5 5 | ||
|
||
Set a lower session default value for nprobe | ||
set session fb_vector_search_nprobe = 3; | ||
show variables like 'fb_vector_search_nprobe'; | ||
Variable_name Value | ||
fb_vector_search_nprobe 3 | ||
|
||
In spite of LIMIT 100, the following select should only have limited results due to the session nprobe value | ||
select *, fb_vector_l2(vector1, '[0.3, 0.3]') as dis from t1 force index(key1) order by dis limit 100; | ||
id vector1 name dis | ||
4 [0.0004, 0.0004] val4 0.17952032387256622 | ||
3 [0.0003, 0.0003] val3 0.17964020371437073 | ||
2 [0.0002, 0.0002] val2 0.17976008355617523 | ||
1 [0.0001, 0.0001] val1 0.1798800528049469 | ||
0 [0, 0] val0 0.18000000715255737 | ||
1000 [1, 1] val1000 0.9799999594688416 | ||
1001 [1.0001, 0.9999] val1001 0.9800000190734863 | ||
1002 [1.0002, 0.9998] val1002 0.9800001382827759 | ||
1004 [1.0004, 0.9996] val1004 0.9800001978874207 | ||
1003 [1.0003, 0.9997] val1003 0.9800002574920654 | ||
2001 [2.0001, 1.9999] val2001 5.779999732971191 | ||
2003 [2.0003, 1.9997] val2003 5.779999732971191 | ||
2000 [2, 2] val2000 5.78000020980835 | ||
2002 [2.0002, 1.9998] val2002 5.780000686645508 | ||
2004 [2.0004, 1.9996] val2004 5.780000686645508 | ||
SELECT NTOTAL, HIT, MIN_LIST_SIZE, MAX_LIST_SIZE, AVG_LIST_SIZE FROM INFORMATION_SCHEMA.ROCKSDB_VECTOR_INDEX WHERE TABLE_NAME = 't1'; | ||
NTOTAL HIT MIN_LIST_SIZE MAX_LIST_SIZE AVG_LIST_SIZE | ||
50 2 5 5 5 | ||
|
||
Query hint can be used to override the default nprobe | ||
The following SELECT should have only 5 result rows | ||
select /*+ SET_VAR(fb_vector_search_nprobe = 1) */ *, fb_vector_l2(vector1, '[0.3, 0.3]') as dis from t1 force index(key1) order by dis limit 100; | ||
id vector1 name dis | ||
4 [0.0004, 0.0004] val4 0.17952032387256622 | ||
3 [0.0003, 0.0003] val3 0.17964020371437073 | ||
2 [0.0002, 0.0002] val2 0.17976008355617523 | ||
1 [0.0001, 0.0001] val1 0.1798800528049469 | ||
0 [0, 0] val0 0.18000000715255737 | ||
SELECT NTOTAL, HIT, MIN_LIST_SIZE, MAX_LIST_SIZE, AVG_LIST_SIZE FROM INFORMATION_SCHEMA.ROCKSDB_VECTOR_INDEX WHERE TABLE_NAME = 't1'; | ||
NTOTAL HIT MIN_LIST_SIZE MAX_LIST_SIZE AVG_LIST_SIZE | ||
50 3 5 5 5 | ||
|
||
Set a new, lower, session default value for nprobe | ||
set session fb_vector_search_nprobe = 1; | ||
show variables like 'fb_vector_search_nprobe'; | ||
Variable_name Value | ||
fb_vector_search_nprobe 1 | ||
|
||
Less results expected now | ||
select *, fb_vector_l2(vector1, '[0.3, 0.3]') as dis from t1 force index(key1) order by dis limit 100; | ||
id vector1 name dis | ||
4 [0.0004, 0.0004] val4 0.17952032387256622 | ||
3 [0.0003, 0.0003] val3 0.17964020371437073 | ||
2 [0.0002, 0.0002] val2 0.17976008355617523 | ||
1 [0.0001, 0.0001] val1 0.1798800528049469 | ||
0 [0, 0] val0 0.18000000715255737 | ||
SELECT NTOTAL, HIT, MIN_LIST_SIZE, MAX_LIST_SIZE, AVG_LIST_SIZE FROM INFORMATION_SCHEMA.ROCKSDB_VECTOR_INDEX WHERE TABLE_NAME = 't1'; | ||
NTOTAL HIT MIN_LIST_SIZE MAX_LIST_SIZE AVG_LIST_SIZE | ||
50 4 5 5 5 | ||
|
||
Query hint can be used to override the default nprobe and expand search space | ||
The following SELECT should have 15 result rows | ||
select /*+ SET_VAR(fb_vector_search_nprobe = 3) */ *, fb_vector_l2(vector1, '[0.3, 0.3]') as dis from t1 force index(key1) order by dis limit 100; | ||
id vector1 name dis | ||
4 [0.0004, 0.0004] val4 0.17952032387256622 | ||
3 [0.0003, 0.0003] val3 0.17964020371437073 | ||
2 [0.0002, 0.0002] val2 0.17976008355617523 | ||
1 [0.0001, 0.0001] val1 0.1798800528049469 | ||
0 [0, 0] val0 0.18000000715255737 | ||
1000 [1, 1] val1000 0.9799999594688416 | ||
1001 [1.0001, 0.9999] val1001 0.9800000190734863 | ||
1002 [1.0002, 0.9998] val1002 0.9800001382827759 | ||
1004 [1.0004, 0.9996] val1004 0.9800001978874207 | ||
1003 [1.0003, 0.9997] val1003 0.9800002574920654 | ||
2001 [2.0001, 1.9999] val2001 5.779999732971191 | ||
2003 [2.0003, 1.9997] val2003 5.779999732971191 | ||
2000 [2, 2] val2000 5.78000020980835 | ||
2002 [2.0002, 1.9998] val2002 5.780000686645508 | ||
2004 [2.0004, 1.9996] val2004 5.780000686645508 | ||
SELECT NTOTAL, HIT, MIN_LIST_SIZE, MAX_LIST_SIZE, AVG_LIST_SIZE FROM INFORMATION_SCHEMA.ROCKSDB_VECTOR_INDEX WHERE TABLE_NAME = 't1'; | ||
NTOTAL HIT MIN_LIST_SIZE MAX_LIST_SIZE AVG_LIST_SIZE | ||
50 5 5 5 5 | ||
|
||
Add new vectors into the vector database to verify that they become part of the search | ||
insert into t1 values (1010, json_array(0.32, 0.32), 'val1010'); | ||
insert into t1 values (1011, json_array(0.28, 0.28), 'val1011'); | ||
|
||
Newly added vectors should show up in the previous search | ||
select /*+ SET_VAR(fb_vector_search_nprobe = 3) */ *, fb_vector_l2(vector1, '[0.3, 0.3]') as dis from t1 force index(key1) order by dis limit 100; | ||
id vector1 name dis | ||
1010 [0.32, 0.32] val1010 0.0007999984663911164 | ||
1011 [0.28, 0.28] val1011 0.0008000008529052138 | ||
4 [0.0004, 0.0004] val4 0.17952032387256622 | ||
3 [0.0003, 0.0003] val3 0.17964020371437073 | ||
2 [0.0002, 0.0002] val2 0.17976008355617523 | ||
1 [0.0001, 0.0001] val1 0.1798800528049469 | ||
0 [0, 0] val0 0.18000000715255737 | ||
1000 [1, 1] val1000 0.9799999594688416 | ||
1001 [1.0001, 0.9999] val1001 0.9800000190734863 | ||
1002 [1.0002, 0.9998] val1002 0.9800001382827759 | ||
1004 [1.0004, 0.9996] val1004 0.9800001978874207 | ||
1003 [1.0003, 0.9997] val1003 0.9800002574920654 | ||
2001 [2.0001, 1.9999] val2001 5.779999732971191 | ||
2003 [2.0003, 1.9997] val2003 5.779999732971191 | ||
2000 [2, 2] val2000 5.78000020980835 | ||
2002 [2.0002, 1.9998] val2002 5.780000686645508 | ||
2004 [2.0004, 1.9996] val2004 5.780000686645508 | ||
SELECT NTOTAL, HIT, MIN_LIST_SIZE, MAX_LIST_SIZE, AVG_LIST_SIZE FROM INFORMATION_SCHEMA.ROCKSDB_VECTOR_INDEX WHERE TABLE_NAME = 't1'; | ||
NTOTAL HIT MIN_LIST_SIZE MAX_LIST_SIZE AVG_LIST_SIZE | ||
52 6 5 7 5 | ||
|
||
Valid values for nprobe are between 1 and 10000 | ||
By providing nprobe as < 1 or > 10000, the nprobe hint will get truncated to the min/max limits (1 and 10000). Examples below: | ||
select /*+ SET_VAR(fb_vector_search_nprobe = 0) */ *, fb_vector_l2(vector1, '[0.3, 0.3]') as dis from t1 force index(key1) order by dis limit 100; | ||
id vector1 name dis | ||
1010 [0.32, 0.32] val1010 0.0007999984663911164 | ||
1011 [0.28, 0.28] val1011 0.0008000008529052138 | ||
4 [0.0004, 0.0004] val4 0.17952032387256622 | ||
3 [0.0003, 0.0003] val3 0.17964020371437073 | ||
2 [0.0002, 0.0002] val2 0.17976008355617523 | ||
1 [0.0001, 0.0001] val1 0.1798800528049469 | ||
0 [0, 0] val0 0.18000000715255737 | ||
Warnings: | ||
Warning 1292 Truncated incorrect fb_vector_search_nprobe value: '0' | ||
SELECT NTOTAL, HIT, MIN_LIST_SIZE, MAX_LIST_SIZE, AVG_LIST_SIZE FROM INFORMATION_SCHEMA.ROCKSDB_VECTOR_INDEX WHERE TABLE_NAME = 't1'; | ||
NTOTAL HIT MIN_LIST_SIZE MAX_LIST_SIZE AVG_LIST_SIZE | ||
52 7 5 7 5 | ||
with search as (select /*+ SET_VAR(fb_vector_search_nprobe = 10001) */ *, fb_vector_l2(vector1, '[0.3, 0.3]') as dis from t1 force index(key1) order by dis limit 100) select COUNT(*) from search; | ||
COUNT(*) | ||
52 | ||
Warnings: | ||
Warning 1292 Truncated incorrect fb_vector_search_nprobe value: '10001' | ||
SELECT NTOTAL, HIT, MIN_LIST_SIZE, MAX_LIST_SIZE, AVG_LIST_SIZE FROM INFORMATION_SCHEMA.ROCKSDB_VECTOR_INDEX WHERE TABLE_NAME = 't1'; | ||
NTOTAL HIT MIN_LIST_SIZE MAX_LIST_SIZE AVG_LIST_SIZE | ||
52 8 5 7 5 | ||
with search as (select /*+ SET_VAR(fb_vector_search_nprobe = 1G) */ *, fb_vector_l2(vector1, '[0.3, 0.3]') as dis from t1 force index(key1) order by dis limit 100) select COUNT(*) from search; | ||
COUNT(*) | ||
52 | ||
Warnings: | ||
Warning 1292 Truncated incorrect fb_vector_search_nprobe value: '1073741824' | ||
SELECT NTOTAL, HIT, MIN_LIST_SIZE, MAX_LIST_SIZE, AVG_LIST_SIZE FROM INFORMATION_SCHEMA.ROCKSDB_VECTOR_INDEX WHERE TABLE_NAME = 't1'; | ||
NTOTAL HIT MIN_LIST_SIZE MAX_LIST_SIZE AVG_LIST_SIZE | ||
52 9 5 7 5 | ||
|
||
On providing value other than unsigned int, the nprobe hint will become ineffective, and the session variable value will be used | ||
Example of bad syntax for nprobe query hint | ||
select /*+ SET_VAR(fb_vector_search_nprobe = -1) */ *, fb_vector_l2(vector1, '[0.3, 0.3]') as dis from t1 force index(key1) order by dis limit 100; | ||
id vector1 name dis | ||
1010 [0.32, 0.32] val1010 0.0007999984663911164 | ||
1011 [0.28, 0.28] val1011 0.0008000008529052138 | ||
4 [0.0004, 0.0004] val4 0.17952032387256622 | ||
3 [0.0003, 0.0003] val3 0.17964020371437073 | ||
2 [0.0002, 0.0002] val2 0.17976008355617523 | ||
1 [0.0001, 0.0001] val1 0.1798800528049469 | ||
0 [0, 0] val0 0.18000000715255737 | ||
Warnings: | ||
Warning 1064 Optimizer hint syntax error near '-1) */ *, fb_vector_l2(vector1, '[0.3, 0.3]') as dis from t1 force index(key1) ' at line 1 | ||
SELECT NTOTAL, HIT, MIN_LIST_SIZE, MAX_LIST_SIZE, AVG_LIST_SIZE FROM INFORMATION_SCHEMA.ROCKSDB_VECTOR_INDEX WHERE TABLE_NAME = 't1'; | ||
NTOTAL HIT MIN_LIST_SIZE MAX_LIST_SIZE AVG_LIST_SIZE | ||
52 10 5 7 5 | ||
select /*+ SET_VAR(fb_vector_search_nprobe = 0.1) */ *, fb_vector_l2(vector1, '[0.3, 0.3]') as dis from t1 force index(key1) order by dis limit 100; | ||
id vector1 name dis | ||
1010 [0.32, 0.32] val1010 0.0007999984663911164 | ||
1011 [0.28, 0.28] val1011 0.0008000008529052138 | ||
4 [0.0004, 0.0004] val4 0.17952032387256622 | ||
3 [0.0003, 0.0003] val3 0.17964020371437073 | ||
2 [0.0002, 0.0002] val2 0.17976008355617523 | ||
1 [0.0001, 0.0001] val1 0.1798800528049469 | ||
0 [0, 0] val0 0.18000000715255737 | ||
Warnings: | ||
Warning 1232 Incorrect argument type to variable 'fb_vector_search_nprobe' | ||
SELECT NTOTAL, HIT, MIN_LIST_SIZE, MAX_LIST_SIZE, AVG_LIST_SIZE FROM INFORMATION_SCHEMA.ROCKSDB_VECTOR_INDEX WHERE TABLE_NAME = 't1'; | ||
NTOTAL HIT MIN_LIST_SIZE MAX_LIST_SIZE AVG_LIST_SIZE | ||
52 11 5 7 5 | ||
select /*+ SET_VAR(fb_vector_search_nprobe = 1.0) */ *, fb_vector_l2(vector1, '[0.3, 0.3]') as dis from t1 force index(key1) order by dis limit 100; | ||
id vector1 name dis | ||
1010 [0.32, 0.32] val1010 0.0007999984663911164 | ||
1011 [0.28, 0.28] val1011 0.0008000008529052138 | ||
4 [0.0004, 0.0004] val4 0.17952032387256622 | ||
3 [0.0003, 0.0003] val3 0.17964020371437073 | ||
2 [0.0002, 0.0002] val2 0.17976008355617523 | ||
1 [0.0001, 0.0001] val1 0.1798800528049469 | ||
0 [0, 0] val0 0.18000000715255737 | ||
Warnings: | ||
Warning 1232 Incorrect argument type to variable 'fb_vector_search_nprobe' | ||
SELECT NTOTAL, HIT, MIN_LIST_SIZE, MAX_LIST_SIZE, AVG_LIST_SIZE FROM INFORMATION_SCHEMA.ROCKSDB_VECTOR_INDEX WHERE TABLE_NAME = 't1'; | ||
NTOTAL HIT MIN_LIST_SIZE MAX_LIST_SIZE AVG_LIST_SIZE | ||
52 12 5 7 5 | ||
select /*+ SET_VAR(fb_vector_search_nprobe =A) */ *, fb_vector_l2(vector1, '[0.3, 0.3]') as dis from t1 force index(key1) order by dis limit 100; | ||
id vector1 name dis | ||
1010 [0.32, 0.32] val1010 0.0007999984663911164 | ||
1011 [0.28, 0.28] val1011 0.0008000008529052138 | ||
4 [0.0004, 0.0004] val4 0.17952032387256622 | ||
3 [0.0003, 0.0003] val3 0.17964020371437073 | ||
2 [0.0002, 0.0002] val2 0.17976008355617523 | ||
1 [0.0001, 0.0001] val1 0.1798800528049469 | ||
0 [0, 0] val0 0.18000000715255737 | ||
Warnings: | ||
Warning 1232 Incorrect argument type to variable 'fb_vector_search_nprobe' | ||
SELECT NTOTAL, HIT, MIN_LIST_SIZE, MAX_LIST_SIZE, AVG_LIST_SIZE FROM INFORMATION_SCHEMA.ROCKSDB_VECTOR_INDEX WHERE TABLE_NAME = 't1'; | ||
NTOTAL HIT MIN_LIST_SIZE MAX_LIST_SIZE AVG_LIST_SIZE | ||
52 13 5 7 5 | ||
drop table t1; |
Oops, something went wrong.