首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >你的 RAG 慢,可能不是模型的锅揭秘 Lance:一个让 Parquet 都紧张的「AI 原生」列式格式

你的 RAG 慢,可能不是模型的锅揭秘 Lance:一个让 Parquet 都紧张的「AI 原生」列式格式

作者头像
本体与AI
发布2026-09-09 21:00:34
发布2026-09-09 21:00:34
30
举报

上期聊完向量检索那点事,后台一下子涌进来几十条留言。最让我心头一热的是好几位私信:「你这套数据底座,怎么不用 Lance?」说真的,在被你们「安利」之前,我对 Lance 也只是略有耳闻。翻完文档,我只想认真说一句:谢谢你们——读者的水平,又一次把作者托了起来。今天这篇,就当是给那几条留言的正式回复。

做 AI 应用的人,十有八九都踩过同一个坑:向量库塞了几千万条 embedding,一检索就卡成 PPT;想改几条脏数据,发现整个 parquet 文件得重写一遍;图、文、向量散落四处,关联查询写得像一坨意大利面。 这些问题的根,往往不在你的代码,而在底层那个「装数据」的格式——它当初是为报表分析设计的,不是为 AI 检索设计的。

今天聊一个正在 AI 基础设施圈子里悄悄走红的家伙:Lance

◆ ◆ ◆

一、Lance 到底是什么?

一句话:Lance 是一个为 AI / 机器学习工作负载重新设计的开源列式存储格式。

它不是「又一个 Parquet」——它是一个包含文件格式、表格式、轻量级 catalog 规范三层的完整湖仓格式。LanceDB 团队当初在做向量数据库时,翻遍了市面上的格式,发现没有哪个能同时满足「扫描快 + 随机读快 + 版本化更新」这三个看似矛盾的目标,于是从零写了一个。

Lance 的诞生有学术背书:2025 年 4 月,团队在 arXiv 上发表了论文《Lance: Efficient Random Access in Columnar Storage through Adaptive Structural Encodings》,系统阐述了其核心编码方案。

技术底子:核心用 Rust 写,Python / JS 绑定通过 PyO3 / Napi 实现,底层基于 Apache Arrow 内存模型。这意味着它与 Pandas、Polars、DuckDB 等生态实现零摩擦对接——数据以 Arrow 格式在内存和磁盘之间直接传递,无需序列化开销。

二、为什么 Parquet 在 AI 时代「不够用了」

不是 Parquet 不好——它依然是离线分析场景的王者。问题是,AI 工作负载的读写模式和报表分析完全不同。Parquet 的核心假设是「数据写一次、扫全表、不改了」,而 AI 场景需要的是「高频随机读、增量更新、多模态一起查」。

两个点展开说一下:

(1)Row Group 的双刃剑。 Parquet 把数据按行切成 Row Group(通常 512MB~1GB),每个 Row Group 内部按列存。这让你扫全表时吞吐极高——但想取某一行,你得先把整个 Row Group 的某列解压出来。论文指出,Parquet 在默认配置下随机读性能很差(约 6K 行/秒),但通过调优(禁用页级统计、缩小页大小、使用 page offset index)也可以做到和 Lance 接近(~400K 行/秒)。问题在于:这些调优会显著增加内存占用——每十亿条向量需要额外约 20GB RAM 来缓存偏移索引。

(2)更新就是重写。 Parquet 本身是不可变的,任何增删改本质上都是整文件重写,在云存储上的开销尤其大。

直接上对照表,一目了然:

维度

Parquet

Lance

读单条记录

默认慢(需解压整个 Column Chunk + 遍历页)

快(固定大小页,按行号直接定位 + 一次解压)

更新 / 删除

不可变,增删改即整文件重写

支持原地追加、删除位图标记、版本管理

向量检索

不原生支持,需外部向量库

原生支持向量列 + IVF_PQ / HNSW 索引

多模态

可存二进制,但无特殊优化

图 / 文 / 向量 / 视频同表存放,大 blob 支持懒加载

数据跳过

靠 ColumnChunk 级 min/max 统计(行组粒度)

逐页级 min/max + 自适应索引,跳过粒度更细

列添加

全表重写

零拷贝追加(只写新列数据)

Lance 的论文中也坦承,Parquet 经过正确配置后随机访问性能只有 Lance 的 2~5 倍差距,并非「数十上百倍」那么悬殊——大幅领先主要出现在向量检索场景(Parquet 的 page offset index 内存占用在向量场景下会爆炸,而 Lance 不会)。

三、Lance 的架构核心:Adaptive Structural Encoding

Lance 性能的秘密藏在它的编码方案里。它抛弃了 Parquet 的 Dremel 编码(repetition/definition levels),而是采用自适应结构编码——根据数据宽度自动切换两种策略:

宽数据(如向量/图片/文本):Full Zip 编码

  • 每个值独立存储,存取复杂度 O(1)
  • 读取第 n 行时,直接计算偏移量、一次磁盘寻道 + 一次解压即可拿到
  • 没有重复的页偏移索引,内存占用极低

窄数据(如浮点数/整数/短字符串):Miniblock 编码

  • 每 4~8KB 数据打包成一个 miniblock,metadata 极轻
  • 读取时先定位到 block,再 block 内顺序扫描目标行
  • 适合小标量值的批量读取

这套方案的巧妙之处在于:两种编码可以在同一张表的不同列上共存。图片列用 Full Zip、ID 列用 Miniblock、embedding 列用 Full Zip + 向量索引——互不影响,各自最优。

其他架构要点:

  • Fragment 取代 Row Group。一次写入生成一个 Fragment(可独立压缩/索引),避免了 Parquet 那种「写完一个 Row Group 才知道 schema 全不全」的问题。
  • Manifest + 版本管理。每个版本由一个 immutable 的 Manifest 文件描述,指向该版本有效的 Fragment 和索引列表。查询按版本号寻址,天然支持「时间旅行」。
  • 删除位图。删除行不重写数据,只在对应 Fragment 写入一个位图标记已删行。数据实际回收由 compaction 完成。
  • 零拷贝列追加。新增列只会写入新数据文件,旧数据完全不动——这对特征工程场景极为重要。

四、三张王牌

1. 随机访问性能

论文实测数据:在 NVMe 磁盘上,Lance 可实现 ~400K 行/秒的随机读取(单线程),基本逼近系统调用开销的物理上限。这得益于 Full Zip 编码的 O(1) 行定位和 miniblock 的低 metadata 开销。对 RAG 检索、训练样本随机抽选来说,这是实打实的吞吐提升。

2. 零拷贝版本管理

每次写入产生一个新版本,旧版本仍可查询和回滚。更关键的是:版本之间共享未修改的数据文件。创建 100 个版本不等于复制 100 份数据——只有增量的那部分写入新的 Fragment。配合 compaction 定期合并小 Fragment、回收已删行的空间,版本管理的存储开销非常可控。

3. 为向量和多模态而生

一个数据集里同时存放图片路径、文本、embedding 向量,检索时一次 IO 全拿到。Lance 原生支持 IVF_PQ(倒排 + 乘积量化)和 HNSW 两种 ANN 索引,索引与数据版本一致,不存在「数据更新了、索引还是旧的」的脱节问题。

五、30 秒上手:写进去,建索引,查出来

代码语言:javascript
复制
import lance
import pyarrow as pa

# 1. 一份带向量的数据
tbl = pa.table({
    "id":     [1, 2, 3],
    "text":   ["猫", "狗", "鸟"],
    "vector": [[0.1, 0.2], [0.3, 0.4], [0.5, 0.6]],
})

# 2. 写进 Lance 数据集
ds = lance.write_dataset(tbl, "data.lance")

# 3. 为向量列建 IVF_PQ 索引
ds.create_index("vector", index_type="IVF_PQ")

# 4. 最近邻检索
rs = ds.to_table(
    nearest={"column": "vector", "q": [0.1, 0.2], "k": 2}
).to_pandas()
print(rs)

安装只需 pip install lance(旧版包名 pylance 仍可用,但推荐新名)。LanceDB 在此基础上又包了一层 Table API,支持 SQL 过滤、全文搜索和向量检索的混合查询。

六、谁在用 Lance?

这不是个「实验室玩具」:

  • Netflix:媒体数据湖,用 Lance 存储和检索海量视频元数据及特征
  • Uber:分布式多模态 AI 数据湖,用于自动驾驶数据的存储与查询
  • Exa:下一代搜索引擎,在 Lance 上构建了 PB 级的 AI 数据管道
  • HuggingFace Datasets:OpenVid 数据集直接以 Lance 格式发布,内嵌视频、分镜特征、CLIP embedding 和预建的 IVF_PQ 索引

七、它和本体有什么关系?

  • RAG / GraphRAG:海量文档切片 + embedding 落进 Lance,随机检索延迟从秒级压到毫秒级,知识图谱的向量层有了靠谱的物理底座。
  • 多模态知识库:本体建模常要关联文本、图像、实体向量,Lance 同表存放省去大量 ETL 和跨系统数据搬运。
  • 数据版本与可追溯:本体演化、规则迭代时,哪个数据集版本对应哪版推理结果——Lance 的版本管理天然适配「可解释、可追溯」的合规诉求。
  • 列追加与特征演化:新算出的 embedding 或标注作为新列追加到原表,零拷贝,不影响已有查询。这对持续迭代的本体标注流程来说是实打实的基础设施利好。

数据格式是 AI 时代的地基。地基选错了,上层怎么优化都白搭。——这是一种认知

八、一个更根本的问题:本体时代,数据到底存在哪?还需不需要数据中台?

聊到这,很多老读者应该已经想到了一个更深层的问题——我们搞本体、搞 GraphRAG,天天谈语义模型、实体抽取、关系推理。但这些数据肉身到底该放在哪里?是不是还得搭一个庞然大物一样的数据中台?

现状:数据在「打地鼠」

做个技术架构的人大概都有这个体感:一个 AI 项目跑起来,数据至少散落在四五个系统里——

  • 原始数据(文档、图片、视频)在对象存储(S3 / OSS),按目录组织
  • 结构化元数据在关系库(PostgreSQL),存 tags、labels、来源信息
  • embedding 在向量库(Pinecone / Milvus / Qdrant),做语义检索
  • 实体关系在图数据库(Neo4j / NebulaGraph),做知识推理
  • 训练样本在 Parquet 文件里,供模型消费

每多一个系统,就多一条 ETL 管道、多一套权限体系、多一次同步延迟。中台的价值在这里看似很大——统一入口、集中治理。但代价呢?

数据中台的「三重税」

第一重:模型税。 中台内部用的是星型模型 / 维度建模,天然为报表查询优化的设计。到了 AI 侧,你得再做一次转换——把星型拍平、把维度转向量、把事实表和维度表拼成大宽表。这层转换的成本,往往比中台自身的建设成本还高。

第二重:版本税。 本体是演化的——今天加了两个实体类型,明天换了 embedding 模型,后天改了切分策略。中台的 schema-on-write 模式要求先改模型再灌数据,每次演化都牵一发而动全身。

第三重:ETL 税。 数据从中台到推理管道,要过至少两套 ETL:中台内部生成数据集 → 导出到对象存储 → 再导入到向量库。每一步都是延迟和出错面。

Lance 让「轻底座」成为可能

Lance 的架构恰好击中了以上三个痛点:

一个格式替代多个系统。 Lance 允许你在同一张表里放原始文本、图片 blob、embedding 向量、标签元数据。检索时一次 IO 拿到全部,省去跨系统 join。

列追加替代 schema 变更。 换了 embedding 模型?新算出来的向量作为新列追加到原表。旧向量保留,不影响已有查询。零拷贝,不需要动中台的模型设计。

版本对版本:本体版本 = 数据版本。 你的本体每次迭代,对应 Lance 数据集的一个 commit 版本。回滚本体时回滚数据版本即可。可追溯、可复现。

那么,还需不需要数据中台?

我的判断是:不需要传统意义上的重型数据中台,但需要一个「轻量数据底座」。

两者的区别:

维度

重型数据中台

轻量数据底座

核心假设

数据为报表服务

数据为 AI 服务

数据模型

星型 / 雪花模型

Arrow + 多模态原生

存储策略

数仓 + 数据集市 + 数据湖三层

Lance 统一存储 + 图库做推理

演化代价

schema 变更需停服审批

列追加零成本

系统数量

5~8 个组件是标配

Lance + 图库 + 轻量调度

组合建议:Lance 存实体属性和 embedding,图数据库存关系拓扑,两者在查询层通过检索 API 打通——而不是通过传统 ETL 管道。

Agent 来了,同步模式还顶得住吗?

这个问题再往下挖一层,就是 AI agent 场景里最实际的一个架构分歧:

Agent 应该直接查数据库拿实时数据,还是等中台同步完了再从中台查?

大多数人的第一反应是「走中台」,因为那是当年做数据治理时被反复灌输的最佳实践——数据要先入湖、统一口径、再对外服务。但这个模式在 agent 场景下有三个致命问题:

问题一:同步延迟 = agent 说胡话。 数据中台的同步周期通常是 T+1(小时级算好的),好一点能做到分钟级 CDC。但一个 agent 在对话中要回答「当前订单状态是什么」「这个实体最新的属性值是多少」,它需要的是此刻的数据。一个告诉自己仓库没货、实际 5 分钟前刚补了货的 agent,和「胡言乱语」之间只隔了一次 ETL 延迟。

问题二:同步加重了「本体脱节」。 中台里的数据模型(维度表、事实表)和本体里的语义模型(实体、关系、属性)天然是两套语言。哪怕中台同步完了,agent 还得再做一层「语义映射」——把中台的列名翻译成本体的属性名。多一次映射,多一个出错面,多一层代码维护。

问题三:同步链路越长,agent 的「冷启动」越慢。 新接入一个数据源,中台团队排期开发 ETL → 数据入 lake → 模型评审 → 开放 API。一套流程走下来按周甚至按月计。而 agent 接入一个新实体的方式,理论上只需要在本体里加一个类型定义,数据就能通过 Lance 直查。快了几个数量级。

那 agent 到底应该怎么查?

我给的建议是:不走中台同步这条老路,走「本体即 Schema,Lance 即 Store,Agent 即 Query Engine」的新路。

架构画出来是这样:

代码语言:javascript
复制
Agent(自然语言 / 任务指令)
    ↓
本体查询层(语义解析 → 映射到实体、属性、关系)
    ↓
Lance(实体属性 + embedding) ←→ 图数据库(关系拓扑)
    ↑ 同一份数据,不搬运
业务数据库 / API / 文件(原始数据源)

这套模式的核心差异:

中台同步模式

本体直查模式

数据流向

多源头 → ETL → 中台 → API → Agent

多源头 → Lance 单份存储 → 本体层 → Agent

延迟

T+1 到分钟级

秒级

语义对齐

需两次映射(源→中台模型→本体)

只需一次(Lance 列直接对应本体属性)

系统数量

数据源 + ETL + 中台 + API + Agent

数据源 + Lance + 本体层 + Agent

维护成本

每加一个数据源 = 一条新 ETL 管道

每加一个数据源 = 一个 Lance 数据集 + 本体类型声明

这里 Lance 的角色很特殊。它不是传统意义上的「数据库」——Lance 数据集可以是直接指向 S3 上 Parquet 文件的虚拟视图(通过 Arrow Dataset API),也可以是一个独立的 Lance 格式存储副本。关键是不需要「先同步到中台再给 agent 用」,agent 可以直接 query Lance,Lance 可以 zero-copy 引用已有数据。

那治理怎么办?

有人会问:不经过中台,数据质量、血缘、权限怎么管?

答案是:这些事不绑定「同步」这一步。 本体层本身就是天然的治理框架——每一个实体类型、属性、关系的定义就是数据标准。权限可以下沉到存储层(Lance 的 catalog 支持细粒度访问控制),血缘由版本管理自动记录。这些在直接查询模式下都能做,不需要先把数据搬到一个专门做治理的系统里。

治理应该寄生在数据流动的路径上,而不是在路径中间修一个大坝。——这是另一种认知

本体时代的数据架构,不应该是「先建一个中台把所有数据管起来」,而是「让数据在存储层就和你的 AI 工作负载对齐」。Lance 这样的格式,恰好让这件事变得可行。

九、泼一盆冷水(真诚版)

  • Lance 还很年轻,BI 工具对接、ETL 生态远不如 Parquet 成熟。你要用 Tableau / Power BI 直查的话暂时走不通。
  • 纯离线报表分析,Parquet 依然够用甚至更优。Lance 的优势不在全表扫描,而在混合负载。
  • 选型建议:AI 检索 / 多模态 / 频繁列演化场景优先 Lance;纯批量分析 / BI / 数仓保留 Parquet。两者不是取代关系,是分工关系
  • 论文也说了:Parquet 经过深度配置后(page offset index、小页大小、禁用字典编码等)随机读并不差,只是在向量场景的内存开销上扛不住。

十、写在最后

我们聊本体、聊大模型、聊 GraphRAG,但经常忽略最底层那块砖——数据是怎么存的。Lance 这类「AI 原生格式」的崛起,本质上在提醒一件事:当工作负载从「人看报表」变成「模型读向量」,整个数据栈都得重做一遍。

你踩过哪些数据格式的坑?Parquet、Lance 还是别的?评论区聊聊,咱们一起把地基打牢。

◆ ◆ ◆

本文由公众号「本体与AI」原创,转载请注明出处。关注我们,持续拆解 AI 时代的数据与知识底座。

参考:LanceDB 团队, 《Lance: Efficient Random Access in Columnar Storage through Adaptive Structural Encodings》, arXiv 2504.15247, 2025

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2026-07-29,如有侵权请联系 cloudcommunity@tencent.com 删除
目录
  • 一、Lance 到底是什么?
  • 二、为什么 Parquet 在 AI 时代「不够用了」
  • 三、Lance 的架构核心:Adaptive Structural Encoding
  • 四、三张王牌
  • 五、30 秒上手:写进去,建索引,查出来
  • 六、谁在用 Lance?
  • 七、它和本体有什么关系?
  • 八、一个更根本的问题:本体时代,数据到底存在哪?还需不需要数据中台?
    • 现状:数据在「打地鼠」
    • 数据中台的「三重税」
    • Lance 让「轻底座」成为可能
    • 那么,还需不需要数据中台?
    • Agent 来了,同步模式还顶得住吗?
    • 那 agent 到底应该怎么查?
    • 那治理怎么办?
  • 九、泼一盆冷水(真诚版)
  • 十、写在最后
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档