通过 Lance 外表可以按向量距离查询最相近的 K 条数据,支持使用向量索引的近似最近邻检索(ANN)和不使用向量索引的精确检索(exact KNN)。检索由 SQL 执行引擎完成还是下推到 Lance,取决于查询执行方式和查询结构,可通过执行计划确认实际路径。
向量检索的执行方式
向量检索中的距离计算、Top-K 选择及 OFFSET 处理,可以由 SQL 执行引擎完成,也可以下推到 Lance。由 SQL 执行引擎完成时,引擎读取 Lance 数据,计算距离并排序选取 Top-K,属于精确检索。下推到 Lance 时,由 Lance 完成上述处理,可以使用向量索引执行 ANN,也可以扫描向量执行 exact KNN。向量检索的执行路径与查询执行方式有关:
查询执行方式 | 向量检索的执行路径 |
行式执行 | 由 SQL 执行引擎计算距离并排序选取 Top-K,不支持检索下推。 |
MPP 并行执行 | 由 SQL 执行引擎计算距离并排序选取 Top-K,不支持检索下推。 |
单节点 IMCI | 满足下推条件时,由 Lance 完成检索;未下推时,由 SQL 执行引擎计算距离并排序选取 Top-K。 |
检索下推到 Lance 的条件
单节点 IMCI 执行时,将向量检索下推到 Lance 需满足以下条件:
执行方式:查询采用单节点 IMCI。MySQL 原生行式执行和 MPP 并行执行尚不支持将向量检索下推到 Lance。
向量列与查询向量:
DISTANCE函数的一个参数为待检索 Lance 外表的VECTOR(N) NOT NULL列,另一个参数为预先给定的非 NULL 查询向量。例如,向量常量或已赋值的用户变量。排序与结果条数:仅按一个
DISTANCE(...)表达式升序排序,并通过LIMIT指定正整数条数,允许非负OFFSET。增加第二个排序键、改为降序,或对排序中的距离表达式再次运算,均不满足该条件。查询结构:需要下推的排序和
LIMIT必须直接作用于同一外表的扫描结果,中间仅允许过滤,不能跨越 JOIN、聚合等其他运算。过滤条件:在 Top-K 之前生效的过滤条件必须能完整下推到 Lance,先完成过滤再选择候选记录。存在需要下推的过滤条件时,还需开启
lance_enable_filter_pushdown;仅能部分下推、仍需由 SQL 执行引擎计算的条件不满足要求。没有过滤条件时,不依赖该开关。其他限制:该次检索的扫描、过滤和输出不能引用
_rowid,远端数据集不能有名为_distance的物理列;同一扫描不能同时采用全文检索、混合检索或按_rowid读取等其他专用读取方式。
ANN 与 exact KNN 的选择规则
满足前述检索下推条件后,imci_enable_vector_search 控制是否使用向量索引:
关闭(OFF):由 Lance 执行 exact KNN,不使用向量索引。
开启(ON):目标向量列有符合要求的索引时,执行 ANN。没有向量索引时,执行 exact KNN。
ANN 要求目标向量列只有一个向量索引,索引中已有数据,且距离度量与查询一致。开启开关后,若已有索引不符合这些要求,则不下推检索,由 SQL 执行引擎计算距离并排序。
执行计划验证
通过 EXPLAIN ANALYZE,按下推标记、索引参数和物理算子的顺序检查同一扫描:
Lance Scan Mode: Vector表示向量检索已下推到 Lance,该标记本身不区分 ANN 与 exact KNN。Lance Use Index: false表示未启用向量索引,true表示启用向量索引。是否使用索引完成检索,需检查Lance Plan。Lance Plan中出现ANNSubIndex和ANNIvfPartition,可确认走向量索引检索路径。Lance Nprobes和Lance Refine Factor用于确认搜索参数是否生效。
适用范围
使用向量检索前,确认已满足以下条件:
已满足使用前提与功能限制中的各项要求。
账号具有查询目标表的
SELECT权限。已创建待查询的外表。
CREATE FOREIGN TABLE只创建本地映射,不会构建远端索引。
示例约定
下文示例使用单节点 IMCI 执行,示例开头的 SET SESSION 语句用于强制使用 IMCI、关闭 MPP 并设置向量索引搜索开关,仅影响当前连接。示例还遵循以下约定:
example_*为示例名称,请替换为实际名称;外表列名须与远端列名一致。example_table包含example_id、example_group_id和example_embedding列,其中example_embedding为非空的十维 32 位浮点向量,映射为VECTOR(10)。外表VECTOR列、远端向量列和查询向量的维度必须一致。ANN 示例假设已在远端
example_embedding列创建 L2 IVF_FLAT 索引。
执行基本检索
使用向量索引执行 ANN 检索
连接已启用 IMCI 的查询节点并选择外表所在数据库。以下示例强制使用 IMCI、关闭 MPP,并允许使用向量索引。随后设置查询向量 @query,按距离升序返回最多三条记录。
SET SESSION use_imci_engine = FORCED;
SET SESSION imci_plan_use_mpp = OFF;
SET SESSION imci_enable_vector_search = ON;
SET @query = STRING_TO_VECTOR('[0,1,2,3,4,5,6,7,8,9]');
SELECT example_id
FROM example_table
ORDER BY DISTANCE(example_embedding, @query, 'EUCLIDEAN')
LIMIT 3;
SHOW SESSION STATUS LIKE 'Last_stmt_use_imci';
EXPLAIN ANALYZE
SELECT example_id
FROM example_table
ORDER BY DISTANCE(example_embedding, @query, 'EUCLIDEAN')
LIMIT 3;查询后读取 Last_stmt_use_imci,返回 TRUE 表示实际使用了 IMCI。再通过 EXPLAIN ANALYZE,按执行计划验证一节的方法确认检索下推和 ANN 索引路径。
ANN 返回近似最近邻,实际结果取决于数据、索引和搜索参数。
执行精确检索(exact KNN)
以下示例在单节点 IMCI 中关闭向量索引搜索,并重新设置查询向量。满足前述下推条件时,由 Lance 扫描向量、计算距离并选取 Top-K。
SET SESSION use_imci_engine = FORCED;
SET SESSION imci_plan_use_mpp = OFF;
SET SESSION imci_enable_vector_search = OFF;
SET @query = STRING_TO_VECTOR('[0,1,2,3,4,5,6,7,8,9]');
SELECT example_id
FROM example_table
ORDER BY DISTANCE(example_embedding, @query, 'EUCLIDEAN')
LIMIT 3;
EXPLAIN ANALYZE
SELECT example_id
FROM example_table
ORDER BY DISTANCE(example_embedding, @query, 'EUCLIDEAN')
LIMIT 3;通过 EXPLAIN ANALYZE 确认执行计划显示 Lance Scan Mode: Vector 且 Lance Use Index: false,表示距离计算与 Top-K 选择由 Lance 完成,并未使用向量索引,即精确检索已下推。
执行组合查询
向量检索可以结合标量条件过滤来限定检索范围,也可以通过 LIMIT 和 OFFSET 实现分页。以下两个示例分别初始化单节点 IMCI、开启向量索引搜索并设置查询向量,可在独立连接中执行。
带标量过滤的检索
以下示例开启 lance_enable_filter_pushdown,在 example_group_id=1 的记录中执行向量检索,并返回距离值。
SET SESSION use_imci_engine = FORCED;
SET SESSION imci_plan_use_mpp = OFF;
SET SESSION imci_enable_vector_search = ON;
SET SESSION lance_enable_filter_pushdown = ON;
SET @query = STRING_TO_VECTOR('[0,1,2,3,4,5,6,7,8,9]');
SELECT example_id, example_group_id,
ROUND(DISTANCE(example_embedding, @query, 'EUCLIDEAN'), 6)
AS example_distance
FROM example_table
WHERE example_group_id = 1
ORDER BY DISTANCE(example_embedding, @query, 'EUCLIDEAN')
LIMIT 3;若希望向量检索下推到 Lance,过滤条件需要完整下推到 Lance,从而在选取前 K 条候选数据之前完整执行。若过滤条件无法下推到 Lance,则向量检索改由 SQL 执行引擎处理;可通过 EXPLAIN ANALYZE,按执行计划验证一节的方法检查实际执行方式。
分页查询
以下示例设置向量检索的 LIMIT 和 OFFSET,实现分页查询。
SET SESSION use_imci_engine = FORCED;
SET SESSION imci_plan_use_mpp = OFF;
SET SESSION imci_enable_vector_search = ON;
SET @query = STRING_TO_VECTOR('[0,1,2,3,4,5,6,7,8,9]');
SELECT example_id
FROM example_table
ORDER BY DISTANCE(example_embedding, @query, 'EUCLIDEAN')
LIMIT 2 OFFSET 1;该查询跳过第一条记录,再返回最多两条。向量检索所需候选数包含 LIMIT 和 OFFSET,因此较大的 OFFSET 会增加查询开销。
配置搜索参数
以下参数用于 ANN,exact KNN 不使用这些参数。本节示例均显式开启向量索引搜索,并设置各自的查询向量,避免受到前文精确检索设置的影响。
搜索参数 | 作用 |
| IVF 检索的探测数,0 表示使用 Lance 自动策略。 |
| 候选精排倍数,0 表示不启用。 |
| HNSW 搜索宽度,不影响 Lance IVF_FLAT 索引。 |
会话级配置
以下示例为 IVF_FLAT 检索设置参数。执行前保存原会话值,完成后恢复。
SET SESSION use_imci_engine = FORCED;
SET SESSION imci_plan_use_mpp = OFF;
SET SESSION imci_enable_vector_search = ON;
SET @query = STRING_TO_VECTOR('[0,1,2,3,4,5,6,7,8,9]');
SET @saved_nprobes = @@SESSION.polar_lance_vector_search_nprobes;
SET @saved_refine_factor = @@SESSION.polar_lance_vector_search_refine_factor;
SET SESSION polar_lance_vector_search_nprobes = 1;
SET SESSION polar_lance_vector_search_refine_factor = 2;
SELECT example_id
FROM example_table
ORDER BY DISTANCE(example_embedding, @query, 'EUCLIDEAN')
LIMIT 3;
SET SESSION polar_lance_vector_search_nprobes = @saved_nprobes;
SET SESSION polar_lance_vector_search_refine_factor = @saved_refine_factor;使用 query hint 配置单条语句
仅对一条查询调整参数时,可在 SELECT 后使用 /*+ SET_VAR(参数名=值) */。hint 中的参数在当前语句执行期间覆盖会话值,未指定的参数沿用会话配置。语句结束后自动恢复。
SET SESSION use_imci_engine = FORCED;
SET SESSION imci_plan_use_mpp = OFF;
SET SESSION imci_enable_vector_search = ON;
SET @query = STRING_TO_VECTOR('[0,1,2,3,4,5,6,7,8,9]');
SELECT /*+ SET_VAR(polar_lance_vector_search_nprobes=1)
SET_VAR(polar_lance_vector_search_refine_factor=2) */
example_id
FROM example_table
ORDER BY DISTANCE(example_embedding, @query, 'EUCLIDEAN')
LIMIT 3;使用 EXPLAIN ANALYZE 检查时,需在待分析的 SELECT 中携带相同的 hint。执行计划中的 Lance Nprobes 和 Lance Refine Factor 应和 hint 指定值相同。
SET SESSION use_imci_engine = FORCED;
SET SESSION imci_plan_use_mpp = OFF;
SET SESSION imci_enable_vector_search = ON;
SET @query = STRING_TO_VECTOR('[0,1,2,3,4,5,6,7,8,9]');
EXPLAIN ANALYZE
SELECT /*+ SET_VAR(polar_lance_vector_search_nprobes=1)
SET_VAR(polar_lance_vector_search_refine_factor=2) */
example_id
FROM example_table
ORDER BY DISTANCE(example_embedding, @query, 'EUCLIDEAN')
LIMIT 3;若 Lance 外表的向量列使用 HNSW 索引,可通过 /*+ SET_VAR(polar_vector_index_hnsw_ef_search=64) */ 按语句设置 HNSW 的 ef_search 搜索参数。