DuckDB 与 Lance 湖格式全面集成:从向量搜索到混合检索的完整指南
概述
DuckDB 与 LanceDB 团队正式宣布合作,将 Lance 湖格式 深度集成到 DuckDB 生态中。Lance 是一个专为现代机器学习和 AI 工作负载设计的开放湖格式,支持版本控制、模式演进、索引和事务更新。通过 DuckDB 的 Lance 扩展,用户可以直接通过熟悉的 SQL 接口查询 Lance 数据集,无需离开 DuckDB 的分析工作流。
本文将深入解析这一集成的技术细节、使用方法和性能表现,帮助你全面了解 DuckDB 在 AI 数据检索场景下的全新能力。

什么是 Lance?
Lance 是一个开源的湖格式,专为现代机器学习和 AI 工作负载而设计。与传统的 Parquet 不同,Lance 不仅是文件格式,还是表格式和轻量级编目规范的统一体。
在表格式层面,Lance 支持:
- 版本控制:通过 MVCC 实现多版本并发控制
- 模式演进:轻量级的 schema 变更,只需写入新文件而无需触碰已有数据
- 索引系统:内置向量索引、全文索引和标量索引
- 事务性更新:支持 ACID 风格的增删改操作
- 碎片化布局:将数据存储在小型列式块中,实现高效随机访问
为什么 AI 数据集需要专门的格式?
传统 AI 数据集不仅仅是标量值的行。它们通常包含:
| 数据类型 | 用途 |
|---|---|
| 向量嵌入 | CLIP 图像嵌入、文本嵌入等 |
| 长文本 | 产品描述、对话历史 |
| 图像 | 原始图像字节数据 |
| 音频 | 音频片段数据 |
| 标量元数据 | 过滤、分类、时间戳 |
一个能在这些工作负载上表现良好的格式,需要不仅仅高效存储和扫描列数据,还需要支持搜索、更新和生命周期管理,而无需让用户管理多个不同的系统。
DuckDB-Lance 扩展核心功能
安装与基本使用
使用 DuckDB 的 Lance 扩展非常简单:
-- 加载扩展
INSTALL lance;
LOAD lance;
-- 从 Lance 数据集读取数据
SELECT * FROM read_lance('path/to/dataset.lance');
-- 将数据写入 Lance 数据集
COPY (
SELECT 1 AS animal_id, 'duck' AS name, 92000.0 AS population
UNION ALL
SELECT 2, 'horse', 1200.0
UNION ALL
SELECT 3, 'dragon', 1
) TO 'path/to/out.lance' (FORMAT lance);
直接写入 Lance 表
CREATE TABLE out_table (
animal_id BIGINT,
name VARCHAR,
description VARCHAR
);
COPY out_table TO 'path/to/out.lance' (FORMAT lance, OVERWRITE true);
混合搜索(Hybrid Search)
混合搜索将向量相似性和关键词相关性结合在一个 SQL 查询中:
SELECT
id,
caption,
_hybrid_score,
_distance,
_score
FROM lance_hybrid_search(
'path/to/dataset.lance',
'text_column', -- 文本列
'puppy', -- 搜索关键词
'embedding_col', -- 向量列
10, -- 返回结果数
100 -- 预取因子
)
WHERE prefilter = true
ORDER BY _hybrid_score DESC;
纯向量搜索
SELECT
id,
caption,
_distance
FROM lance_vector_search(
'path/to/dataset.lance',
'embedding_col',
[0.1, 0.2, ..., 0.768], -- 768维查询向量
10 -- top-k
);
全文检索
SELECT id, caption, _score
FROM lance_fts('path/to/dataset.lance', 'text_column', 'puppy', 10);
以表方式附加 Lance 目录
-- 将目录附加为命名空间,实现表级操作
ATTACH 'path/to/dir' AS ns (TYPE lance);
-- 查询 Lance 表如同查询普通表
SELECT * FROM ns.main.my_table WHERE animal_id > 1;
-- 创建向量索引
CREATE INDEX vec_idx ON ns.main.my_table
USING IVF_FLAT(embedding_col, num_partitions = 16, metric_type = 'L2');
-- 索引维护和优化
CALL lance_compact('ns.main.my_table');
CALL lance_cleanup('ns.main.my_table');
DuckDB-Lance 扩展能力全景
| 功能 | 支持方式 | 说明 |
|---|---|---|
| 读取 Lance 数据集 | read_lance() | 直接路径扫描读取 |
| 写入/追加数据 | COPY ... TO ... (FORMAT lance) | 支持追加和覆盖模式 |
| 向量搜索 | lance_vector_search() | 基于 IVF/ANN 的快速向量检索 |
| 全文检索 | lance_fts() | 倒排索引驱动的全文搜索 |
| 混合搜索 | lance_hybrid_search() | 向量 + 关键词的联合搜索 |
| 目录附加 | ATTACH ... (TYPE lance) | 以命名空间方式挂载 |
| 表操作 | CREATE/ALTER/DROP/MERGE | 完整 CRUD 能力 |
| 索引管理 | CREATE INDEX | 向量、标量、全文索引 |
| 维护操作 | lance_compact/cleanup | 碎片整理和清理 |
为什么选择 Lance + DuckDB?
1. 统一的 SQL 分析 + 检索接口
相同的 DuckDB 工作流可以扫描数据集、过滤、与其他表连接、计算聚合,然后对结果集运行向量搜索或混合搜索。这非常适合 AI 应用,其中检索只是更大分析管道中的一步。
2. 超越传统分析的场景
许多 AI 管道需要版本化的数据集、更新、删除、事务性变更、索引管理和模式演进。DuckDB 扩展通过 SQL 暴露这些能力,意味着用户不需要因为数据集需要超越传统分析读取就离开 DuckDB 环境。
3. 从本地文件到远程存储无缝扩展
你可以从本地 .lance 数据集开始,然后迁移到对象存储。扩展也支持 REST 命名空间,使得 DuckDB 可以连接到远程 Lance 编目(包括 LanceDB Enterprise),并将其视为附加数据库。
性能基准测试:LAION-1M 数据集
实验设置
- 数据集:LAION-1M,包含 768 维 CLIP 图像嵌入、原始图像字节、标题文本和标量元数据
- 硬件:Apple MacBook Pro,10 核 M1 Max CPU,32GB 内存
- DuckDB 版本:1.5.2
- 对比格式:
- Parquet:LZ4 压缩的 Parquet 基准,无辅助索引
- DuckDB indexed:加载到 DuckDB 表中,配置 HNSW 向量索引和标量索引
- Lance native:写入 Lance 数据集,配置向量索引和全文索引
工作负载定义
| 工作负载 | 描述 |
|---|---|
text | 基于标题文本的关键词搜索 |
vector_exact | 不使用近似索引的最近邻搜索 |
vector_indexed | 使用向量索引的最近邻搜索 |
hybrid | 文本搜索 + 向量搜索的混合检索 |
blob_read | 获取选定行的图像字节数据,测试大二进制值的随机访问 |
冷启动测试结果
冷启动测试运行在一个全新的 DuckDB 进程中,捕获进程启动、文件打开和首次查询成本:
| 工作负载 | Parquet | DuckDB indexed | Lance native |
|---|---|---|---|
| vector_exact | 695 ms | 703 ms | 695 ms |
| vector_indexed | — | 755 ms | 104 ms |
| hybrid | — | 471 ms | 465 ms |
| blob_read | 1559 ms | 271 ms | 278 ms |
关键发现
向量索引搜索:Lance 在冷启动条件下实现 104ms,比 DuckDB indexed 的 755ms 快 7.2 倍。这是因为 Lance 原生支持 IVF 索引,无需在 DuckDB 中额外构建 HNSW 索引。
混合搜索:Lance 的 465ms 略优于 DuckDB indexed 的 471ms,两者表现接近。但 Lance 的优势在于配置更简单——无需手动配置多种索引类型。
Blob 读取:DuckDB indexed 在 blob 读取上表现最优(271ms),但 Lance 的 278ms 也非常接近,说明 Lance 对二进制数据的存储优化得当。
纯文本搜索:Parquet 在简单的文本搜索中表现尚可(依赖正则匹配),但在向量相关任务上明显落后。
热启动测试结果
缓存和索引预热后,两者都显著优于 Parquet:
| 工作负载 | Parquet | DuckDB indexed | Lance native |
|---|---|---|---|
| vector_exact | 703 ms | 703 ms | 703 ms |
| vector_indexed | — | 755 ms | 104 ms |
| hybrid | — | 471 ms | 465 ms |
| blob_read | 1484 ms | 266 ms | 276 ms |
热启动结果表明,缓存命中后,Parquet 在所有检索任务上的表现都明显落后,而 DuckDB 和 Lance 在缓存后都能提供一致的高性能。
与传统数据格式对比
| 特性 | Parquet | DuckDB (原生) | Lance + DuckDB |
|---|---|---|---|
| 文件格式 | ✅ | ✅ | ✅ |
| 表格式 | ❌ | ❌ | ✅ MVCC 版本控制 |
| 模式演进 | 重写数据 | ❌ | ✅ 增量写入 |
| 向量索引 | 需额外扩展 | 需安装 HNSW | 原生支持 IVF |
| 全文索引 | 需额外扩展 | 需安装 FTI | 原生支持 |
| 事务更新 | ❌ | ❌ | ✅ ACID 增删改 |
| 混合搜索 | ❌ | 需组合 | 原生支持 |
| Blob 存储 | ✅ | ✅ | ✅ 原生支持 |
| 查询接口 | SQL/API | SQL | SQL |
| AI 工作负载 | ⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
| 配置复杂度 | 低 | 中 | 低 |
DuckDB-Lance 的典型应用场景
场景 1:RAG 系统的后端存储
使用 DuckDB 管理 RAG 系统的知识库:
-- 创建嵌入表
ATTACH 'path/to/rag_knowledge' AS rag (TYPE lance);
-- 插入新文档和嵌入
INSERT INTO rag.main.documents (id, text, embedding, metadata)
VALUES (1, 'DuckDB 是一个高性能分析数据库...',
[0.1, 0.2, ...], '{"source": "docs", "version": 1}');
-- 用户查询:混合搜索
SELECT id, text, _hybrid_score
FROM lance_hybrid_search(
'path/to/rag_knowledge',
'text',
'高性能分析数据库',
'embedding',
5
);
场景 2:多模态数据分析
-- 附加多模态数据集
ATTACH 'path/to/multimodal' AS mm (TYPE lance);
-- 按类别过滤 + 向量搜索
SELECT mm.main.images.id, mm.main.images.caption, _distance
FROM lance_vector_search(
'path/to/multimodal',
'clip_embedding',
[0.1, 0.2, ...], -- 查询向量
10
)
WHERE mm.main.images.category = 'nature'
AND mm.main.images.nsfw = false;
场景 3:动态特征工程
-- 增量追加新特征列到现有数据集
ATTACH 'path/to/feature_store' AS fs (TYPE lance);
-- 追加新计算的特征(只需写入新文件)
INSERT INTO fs.main.features (id, feature_vector, source)
SELECT id, compute_features(embedding), 'feature_engineering'
FROM fs.main.features
WHERE feature_vector IS NULL;
与替代方案的比较
vs. Delta Lake + 向量搜索
| 对比维度 | Delta Lake + 向量搜索 | Lance + DuckDB |
|---|---|---|
| 安装配置 | 需要多个扩展 | 一个扩展即可 |
| SQL 体验 | 需要通过 UDF 调用向量搜索 | 原生 SQL 函数 |
| 冷启动性能 | 较慢(HNSW 构建) | 快(IVF 索引预建) |
| 模式演进 | 支持 | 更轻量 |
| 社区生态 | Databricks 生态 | DuckDB + LanceDB 双生态 |
vs. Milvus / Pinecone
| 对比维度 | Milvus / Pinecone | Lance + DuckDB |
|---|---|---|
| 数据管理 | 专用向量数据库 | 统一 SQL 分析 |
| 学习曲线 | 需要学新 API | 只用 SQL |
| 混合分析 | 需要 ETL 到分析引擎 | 原生支持 |
| 部署运维 | 需要独立部署 | 嵌入到 DuckDB |
| 成本 | 云服务费用高 | 开源免费 |
变现建议
1. AI 数据平台服务
利用 DuckDB + Lance 构建 AI 数据管道服务,为企业提供向量数据库托管服务:
- 目标客户:中小型企业需要 RAG 系统但不想自建向量数据库
- 定价策略:按数据存储量和使用量收费,起步价 ¥500/月
- 差异化优势:一站式 SQL 查询 + 向量搜索,无需维护多个系统
2. 多模态数据分析 SaaS
基于 DuckDB-Lance 构建多模态数据分析平台:
- 核心价值:在同一平台上同时分析文本、图像嵌入和结构化数据
- 适用场景:内容审核、图像检索、产品推荐
- 技术壁垒:DuckDB 的嵌入式架构使得部署成本极低
3. 企业知识库解决方案
为中小企业提供基于 DuckDB + Lance 的企业知识库方案:
- 技术栈:DuckDB CLI + Lance 格式 + 简单的 Web 前端
- 优势:无需部署 Milvus/Pinecone,单机即可运行
- 扩展路径:可从单机扩展到远程 Lance 编目
4. 咨询服务
利用 DuckDB-Lance 集成的专业知识提供咨询服务:
- 服务内容:AI 数据架构设计、向量搜索性能优化
- 市场定位:专注于 AI/ML 团队的数据库咨询
- 定价参考:¥2000-5000/天
结论
DuckDB 与 Lance 的集成为 AI 数据工作负载提供了一个强大的新工具。通过统一的 SQL 接口,用户可以同时享受 DuckDB 的分析能力和 Lance 的向量检索、全文搜索和事务性更新能力。性能基准测试显示,在向量索引搜索和混合搜索等关键 AI 负载上,Lance 原生支持带来了显著的性能优势。
对于需要同时处理分析查询和 AI 检索的企业来说,DuckDB-Lance 集成可能是简化技术栈、降低运维成本的理想选择。
本文基于 DuckDB 官方 2026 年 5 月 21 日发布的 “Test-Driving the Lance Lakehouse Format in DuckDB” 文章编写,由 DuckDB 团队与 LanceDB 团队联合开发。