全部产品
Search
文档中心

云原生数据库 PolarDB:最佳实践:查询 OSS 上的 Lance 数据并执行检索

更新时间:Nov 04, 2026

本文基于同一份示例数据,介绍从生成 Lance 数据集、上传 OSS,到创建外表、执行分析和检索的端到端流程。首次接入可按步骤依次操作。已有数据源和外表时,可从对应查询步骤开始。

适用范围

开始操作前,逐项确认以下条件:

  • 集群与账号:已准备开通 Lance 外表能力的 PolarDB 集群,账号具有 SERVER 管理和建表权限。开通条件与功能限制详见使用前提与功能限制。

  • OSS 资源:已准备 OSS Bucket 和读取凭据。

  • 节点类型:检索步骤需要已启用 IMCI 的查询节点,创建外表映射时需连接可写节点。

  • 命名约定:本文假设目标数据库 example_db 已创建;文中的 example_*、YOUR_* 均需替换为实际值。为本教程使用独立的 OSS 目录和数据库对象名称。

以下 Python 3.12 环境及依赖仅用于生成示例数据和索引。激活 Python 3.12 环境后,执行以下命令安装依赖:

python -m pip install "pylance==9.0.0" "pyarrow==20.0.0"

步骤一:生成示例数据与索引

使用已安装 Python 依赖的环境运行以下程序,目标数据集目录需尚不存在。程序生成 16 行数据和 10 维 32 位浮点向量,创建 L2 IVF_FLAT 向量索引及全文索引,最后写入 lance_example/example_table.lance。

from pathlib import Path
import lance
import pyarrow as pa

output = Path('lance_example')
output.mkdir(exist_ok=True)
texts = [
    'kitten sleeps', 'puppy', 'puppy puppy', 'puppy puppy puppy',
    'database systems', 'vector search puppy',
    'hybrid puppy puppy puppy puppy', 'quiet landscape',
    'puppy retrieval', 'full text search', 'puppy puppy guide',
    'nearest neighbor', 'puppy notes',
    'ranking fusion puppy puppy puppy', 'storage engine', 'puppy tutorial',
]
schema = pa.schema([
    pa.field('id', pa.int64(), nullable=False),
    pa.field('group_id', pa.int32(), nullable=False),
    pa.field('text', pa.string(), nullable=False),
    pa.field('embedding', pa.list_(pa.float32(), 10), nullable=False),
])
table = pa.table({
    'id': list(range(16)),
    'group_id': [i % 2 for i in range(16)],
    'text': texts,
    'embedding': [[float(i + j) for j in range(10)] for i in range(16)],
}, schema=schema)
dataset = lance.write_dataset(table, str(output / 'example_table.lance'), mode='create')
dataset.create_index('embedding', 'IVF_FLAT', name='embedding_l2',
                     metric='L2', num_partitions=1)
dataset.create_scalar_index('text', 'INVERTED', name='text_inverted')
assert dataset.count_rows() == 16
print('Created one indexed dataset with 16 rows and 10-dimensional vectors.')

步骤二:上传完整数据集

将 lance_example/example_table.lance 完整数据集目录上传到 OSS Bucket YOUR_OSS_BUCKET 的独立前缀 example_warehouse 下。上传后,数据集位置应为 oss://YOUR_OSS_BUCKET/example_warehouse/example_table.lance。上传时保留完整目录结构,包括数据文件、manifest 和索引。上传完成并确认查询节点具备读取权限后,再创建外表。

步骤三:创建数据源和外表

连接可写节点,选择目标数据库 example_db,将凭据和路径替换为实际配置后,执行以下语句。

USE example_db;

CREATE SERVER example_oss
FOREIGN DATA WRAPPER lance
OPTIONS (EXTRA_SERVER_INFO '{
  "lance_direct_oss_endpoint":"YOUR_OSS_ENDPOINT",
  "lance_direct_oss_bucket":"YOUR_OSS_BUCKET",
  "lance_direct_oss_warehouse_prefix":"example_warehouse",
  "lance_direct_oss_access_key_id":"YOUR_OSS_ACCESS_KEY_ID",
  "lance_direct_oss_access_key_secret":"YOUR_OSS_ACCESS_KEY_SECRET"
}');

CREATE FOREIGN TABLE example_table FROM CONNECTION 'server://example_oss/example_table.lance';

SHOW CREATE TABLE example_table;

通过 SHOW CREATE TABLE 确认外表包含 id、group_id、text,以及类型为 VECTOR(10) 的 embedding 列。已有同名 SERVER 或外表时,使用独立名称并相应调整后续引用。

步骤四:查询数据

连接 PolarDB 集群,选择数据库 example_db,设置 use_imci_engine = OFF,使用行式引擎执行查询。

USE example_db;

SET SESSION use_imci_engine = OFF;

SELECT COUNT(*) AS row_count, SUM(id) AS id_sum
FROM example_table;

SELECT id, group_id, text
FROM example_table
WHERE id IN (1, 2, 5) ORDER BY id;

本示例的预期统计结果为 16 行、id 总和 120;过滤查询预期返回 id 1、2、5。若结果不符合预期,先检查外表映射和上传内容,再继续检索。

步骤五:使用 IMCI 执行分析和向量检索

本步骤使用单节点 IMCI 演示分析查询和向量检索。

说明

对于大数据量分析查询,也可使用 IMCI 的 MPP 并行执行能力。开通条件、配置及执行验证方法参见MPP 并行执行。本例中的向量索引检索仍需使用单节点 IMCI。

连接已启用 IMCI 的查询节点,选择数据库 example_db。设置会话参数 use_imci_engine = FORCED 和 imci_plan_use_mpp = OFF,启用单节点 IMCI。执行分析查询后,读取 Last_stmt_use_imci 确认上一条查询是否使用了 IMCI。随后设置 imci_enable_vector_search = ON,允许符合条件的查询使用向量索引加速检索。最后执行向量检索,并使用 EXPLAIN ANALYZE 分析执行计划。

USE example_db;

SET SESSION use_imci_engine = FORCED;
SET SESSION imci_plan_use_mpp = OFF;

SELECT COUNT(*) AS row_count, SUM(id) AS id_sum
FROM example_table;

SHOW SESSION STATUS LIKE 'Last_stmt_use_imci';

SET SESSION imci_enable_vector_search = ON;

SET @query = STRING_TO_VECTOR('[0,1,2,3,4,5,6,7,8,9]');

SELECT id
FROM example_table
ORDER BY DISTANCE(embedding, @query, 'EUCLIDEAN')
LIMIT 3;

EXPLAIN ANALYZE
SELECT id
FROM example_table
ORDER BY DISTANCE(embedding, @query, 'EUCLIDEAN')
LIMIT 3;

本示例的统计查询预期返回 16 行、id 总和 120。Last_stmt_use_imci 返回 TRUE 表示上一条统计查询使用了 IMCI。向量 Top-K 检索预期依次返回 id 0、1、2。EXPLAIN ANALYZE 的执行计划显示 Lance Scan Mode: Vector 和 Lance Use Index: true,且 Lance Plan 中包含 ANNSubIndex 和 ANNIvfPartition,可确认本例实际使用了向量索引。

步骤六:执行全文检索

本步骤使用单节点 IMCI 执行全文检索。

说明

如需通过 MySQL 行式执行全文检索,需在创建外表时为查询字段声明匹配的单列 FULLTEXT KEY。该声明用于指定本地全文检索字段,不会创建或修改远端 Lance 全文索引。

连接已启用 IMCI 的查询节点,选择数据库 example_db。设置 use_imci_engine = FORCED 和 imci_plan_use_mpp = OFF,启用单节点 IMCI。再设置 imci_enable_fts_query = ON 和 imci_enable_fts_score_streaming = ON,分别开启 FTS 查询优化和流式评分。执行全文检索语句后,读取 Last_stmt_use_imci 确认上一条全文检索是否使用了 IMCI。

USE example_db;

SET SESSION use_imci_engine = FORCED;
SET SESSION imci_plan_use_mpp = OFF;
SET SESSION imci_enable_fts_query = ON;
SET SESSION imci_enable_fts_score_streaming = ON;

SELECT id,
  MATCH(text) AGAINST('puppy' IN NATURAL LANGUAGE MODE) AS score
FROM example_table
WHERE MATCH(text) AGAINST('puppy' IN NATURAL LANGUAGE MODE)
ORDER BY score DESC, id
LIMIT 3;

SHOW SESSION STATUS LIKE 'Last_stmt_use_imci';

全文检索结果的前三个 id 预期为 3、2、6。远端 INVERTED 全文索引已在步骤一创建,单节点 IMCI 无需本地 FULLTEXT KEY 声明即可使用该索引。

步骤七:执行混合检索

连接已启用 IMCI 的查询节点,选择数据库 example_db。设置单节点 IMCI、向量检索和全文检索参数,并初始化查询向量变量 @query。随后执行混合检索,并使用 EXPLAIN ANALYZE 分析执行计划。

USE example_db;

SET SESSION use_imci_engine = FORCED;
SET SESSION imci_plan_use_mpp = OFF;
SET SESSION imci_enable_vector_search = ON;
SET SESSION imci_enable_fts_query = ON;

SET @query = STRING_TO_VECTOR('[0,1,2,3,4,5,6,7,8,9]');

SELECT id,
  LANCE_HYBRID_SCORE(
    DISTANCE(embedding, @query, 'EUCLIDEAN'),
    text, 'puppy', 0.5
  ) AS hybrid_score
FROM example_table
ORDER BY hybrid_score
DESC LIMIT 4;

EXPLAIN ANALYZE
SELECT id,
  LANCE_HYBRID_SCORE(
    DISTANCE(embedding, @query, 'EUCLIDEAN'),
    text, 'puppy', 0.5
  ) AS hybrid_score
FROM example_table
ORDER BY hybrid_score
DESC LIMIT 4;

本例的 id 顺序预期为 3、2、6、1,EXPLAIN ANALYZE 的执行计划显示 Hybrid 模式,可确认混合检索生效。

步骤八:清理示例对象

停止相关查询,连接可写节点并选择示例数据库 example_db,执行以下语句,依次删除本文使用的 example_table 外表和数据源连接。

USE example_db;

DROP FOREIGN TABLE example_table;

DROP SERVER example_oss;

删除外表和 SERVER 不会删除 OSS 数据或索引。需要清理 OSS 时,先确认数据集未被其他查询或应用引用,再删除本教程创建的独立目录。