Lance 格式外部表使用指南
概述
Lance 是专为机器学习设计的列式存储格式,原生支持向量数据和 ANN(近似最近邻)索引。Lakehouse 通过外部表机制直接读取存储在 OSS 上的 Lance 数据集,无需数据迁移即可执行向量相似度搜索。
适用场景:向量检索、图像/文本语义搜索、RAG 知识库查询、推荐系统召回。
快速导航
涉及的 SQL 命令
命令 / 函数 用途 适用场景 CREATE STORAGE CONNECTIONCREATE STORAGE CONNECTION
创建 OSS 访问凭证 首次接入 OSS 时执行一次 CREATE EXTERNAL TABLE ... USING LANCECREATE EXTERNAL TABLE ... USING LANCE
挂载 Lance 数据集为外部表 每个 Lance 数据集执行一次 DESCRIBE TABLEDESCRIBE TABLE
查看列定义和向量维度 确认 schema 是否与 Lance 文件一致 SHOW CREATE TABLESHOW CREATE TABLE
反查完整 DDL 排查 LOCATION / CONNECTION 配置 cosine_distance(a, b)cosine_distance(a, b)
余弦距离,值域 [0, 2],越小越相似 文本/图像语义相似度搜索 l2_distance(a, b)l2_distance(a, b)
欧氏距离,值域 [0, +∞) 空间距离、图像特征匹配
前置准备
本指南所有示例基于以下测试数据集:
⚠️ 网络要求 :Lakehouse 集群必须与 OSS bucket 在同一云厂商(本例为阿里云)。跨云访问(如腾讯云集群访问阿里云 OSS)会因网络不通导致查询超时。
场景一:创建 Lance 外部表
创建 Storage Connection
CREATE STORAGE CONNECTION IF NOT EXISTS conn_oss
TYPE oss
ENDPOINT = 'oss-cn-hangzhou.aliyuncs.com'
ACCESS_ID = '<your-access-key-id>'
ACCESS_KEY = '<your-access-key-secret>';
验证连接是否创建成功:
DESCRIBE CONNECTION conn_oss;
实测输出:
info_name | info_value
-----------+------------------------------
name | conn_oss
type | OSS
enabled | ENABLED
ACCESS_ID | LTAI5t********************
ENDPOINT | oss-cn-hangzhou.aliyuncs.com
创建 Lance 外部表
CREATE EXTERNAL TABLE IF NOT EXISTS `doc_lance_cosine` (
`id` bigint,
`key` string,
`type` string,
`meta` string,
`timestamp` timestamp,
`tag` string,
`k_id` string,
`source` string,
`vec` vector(float, 1024)
) USING LANCE
LOCATION 'oss://lakehouse-hz-daily/clickzetta/lance/test_lance_1024_cosine_small.lance'
CONNECTION conn_oss;
关键参数说明 :
USING LANCEUSING LANCE
:指定格式为 Lance。
LOCATIONLOCATION
:OSS 路径,指向 .lance.lance
目录根路径(该目录下需包含 _versions/_versions/
子目录)。
CONNECTIONCONNECTION
:引用已创建的 Storage Connection 名称。
vector(float, N)vector(float, N)
:向量列类型,NN
必须与 Lance 文件中 fixed_size_listfixed_size_list
的维度完全一致,否则查询返回 NULL。
⚠️ 路径验证 :
LOCATIONLOCATION
指向的路径必须是有效的 Lance 数据集(包含
_versions/_versions/
目录)。路径不存在时报错:
Dataset at path xxx was not found: Not found: xxx/_versionsDataset at path xxx was not found: Not found: xxx/_versions
。可用以下脚本提前验证:
python3 -c "
import oss2
auth = oss2.Auth('<access_id>', '<access_key>')
bucket = oss2.Bucket(auth, 'https://oss-cn-hangzhou.aliyuncs.com', '<bucket>')
for obj in oss2.ObjectIterator(bucket, prefix='your/path.lance/', delimiter='/'):
print(obj.common_prefix) # 应包含 _versions/
"
验证外部表创建成功:
SHOW TABLES LIKE 'doc_lance_cosine';
实测输出:
schema_name | table_name | is_external
------------+------------------+------------
public | doc_lance_cosine | true
场景二:基础数据读取
行数统计
SELECT COUNT(*) AS row_count FROM doc_lance_cosine;
实测输出:
row_count
---------
8192
读取标量列
SELECT id, key, source FROM doc_lance_cosine LIMIT 5;
实测输出:
id | key | source
-------+---------+---------
912569 | key_934 | source_7
912608 | key_941 | source_4
912645 | key_287 | source_5
912648 | key_322 | source_8
912678 | key_862 | source_2
读取向量列
SELECT id, vec FROM doc_lance_cosine LIMIT 1;
实测输出(向量值截断显示):
id | vec
-------+--------------------------------------------------------------
912569 | [0.5198276, 0.46438155, 0.032661837, 0.2069788, ... (1024 维)]
标量列过滤
SELECT id, key, source
FROM doc_lance_cosine
WHERE source = 'source_1'
LIMIT 5;
实测输出:
id | key | source
-------+---------+---------
912959 | key_902 | source_1
913180 | key_377 | source_1
913430 | key_714 | source_1
913438 | key_643 | source_1
913582 | key_235 | source_1
分组统计
SELECT source, COUNT(*) AS cnt
FROM doc_lance_cosine
GROUP BY source
ORDER BY cnt DESC;
实测输出:
source | cnt
---------+----
source_7 | 892
source_5 | 839
source_6 | 817
source_4 | 817
source_8 | 816
source_2 | 813
source_0 | 805
source_3 | 803
source_9 | 799
source_1 | 791
10 个 source 分组,总行数 8,192,分布较均匀(每组约 800 行)。
场景三:向量相似度搜索
Top-K 余弦距离搜索
查询与指定向量最相似的 20 条记录,使用
cosine_distancecosine_distance
函数,值越小越相似。
SELECT key,
id,
cosine_distance(
vec,
[-0.017264263704419136, 0.003988612908869982, -0.06441465020179749,
-- ... 共 1024 个浮点数
]
) AS dist
FROM doc_lance_cosine
WHERE cosine_distance(
vec,
[-0.017264263704419136, 0.003988612908869982, -0.06441465020179749,
-- ... 共 1024 个浮点数
]
) <= 1000.0
ORDER BY dist
LIMIT 20;
WHERE cosine_distance(...) <= 1000.0WHERE cosine_distance(...) <= 1000.0
是宽松阈值,用于触发 Lance 的 ANN 索引加速。实际业务中可根据相似度要求收紧阈值(如
<= 0.3<= 0.3
)。
验证向量距离函数精度
用自相似度验证函数正确性(向量与自身的余弦距离应接近 0):
SELECT id, cosine_distance(vec, vec) AS self_dist
FROM doc_lance_cosine
LIMIT 3;
实测输出:
id | self_dist
-------+------------------------
912569 | 5.960464477539063e-8
912608 | -1.1920928955078125e-7
912645 | -1.1920928955078125e-7
自相似度绝对值均小于
1e-61e-6
,符合 float32 精度预期(理论值为 0,浮点误差在正常范围内)。
场景四:混合过滤查询
向量距离过滤与标量列过滤可以组合使用,先用标量条件缩小候选集,再按向量距离排序。
SELECT key,
id,
source,
cosine_distance(vec, vec) AS dist
FROM doc_lance_cosine
WHERE source = 'source_1'
AND cosine_distance(vec, vec) <= 1.0
ORDER BY dist
LIMIT 5;
实测输出:
key | id | source | dist
--------+--------+----------+------------------------
key_902 | 912959 | source_1 | -1.1920928955078125e-7
key_377 | 913180 | source_1 | -1.1920928955078125e-7
key_714 | 913430 | source_1 | -1.1920928955078125e-7
key_643 | 913438 | source_1 | -1.1920928955078125e-7
key_235 | 913582 | source_1 | -1.1920928955078125e-7
仅返回
source = 'source_1'source = 'source_1'
的行,标量过滤与向量距离过滤均生效。
注意事项
向量维度必须精确匹配 :DDL 中
vector(float, N)vector(float, N)
的 NN
必须与 Lance 文件中 fixed_size_listfixed_size_list
的长度完全一致。维度不匹配时查询不报错,但向量距离列返回 NULL。
timestamp 列类型映射 :Lance 中的
timestamptimestamp
类型在 Lakehouse 中可能映射为 bigintbigint
(Unix 时间戳秒数)。SHOW CREATE TABLESHOW CREATE TABLE
显示的实际类型以系统推断为准,DDL 中声明 timestamptimestamp
不影响数据读取。
Lance 版本 :当前支持 Lance v2 格式(
TBLPROPERTIES('lance.version'='2')TBLPROPERTIES('lance.version'='2')
)。
跨云网络 :Lakehouse 集群与 OSS bucket 必须在同一云厂商。跨云访问(如腾讯云集群访问阿里云 OSS)会因网络不通导致查询超时(默认 300s)。
相关文档