Apache Doris 基于 Lance 的向量检索深度解析

简介: Apache Doris 5.0 多模湖仓预告(7)|技术解析篇:随着自动驾驶等多模态应用的发展,大规模数据查询需要同时满足向量检索、条件过滤和业务分析需求。Apache Doris 集成 Lance,支持直接查询 Lance 数据集,并通过并行检索、提前过滤、按需读列和缓存优化提升查询效率。本轮测试中,在 10 亿规模智能驾驶数据的四条件向量检索场景下,Doris + Lance 用时 2.32 秒,相比 Ray + pylance 提升约 10.87 倍。本文将介绍 Doris 与 Lance 的集成机制、查询能力及性能表现。

导读:Apache Doris 5.0 多模湖仓预告(7)|技术解析篇:随着自动驾驶等多模态应用的发展,大规模数据查询需要同时满足向量检索、条件过滤和业务分析需求。Apache Doris 集成 Lance,支持直接查询 Lance 数据集,并通过并行检索、提前过滤、按需读列和缓存优化提升查询效率。本轮测试中,在 10 亿规模智能驾驶数据的四条件向量检索场景下,Doris + Lance 用时 2.32 秒,相比 Ray + pylance 提升约 10.87 倍。本文将介绍 Doris 与 Lance 的集成机制、查询能力及性能表现。

作者:李文强,SelectDB 多模湖仓负责人


在智能驾驶、多模态搜索等场景中,数据规模正在快速增长。一条查询往往不只是“找最相似的几个样本”,还需要同时满足车型、时间、设备、区域等业务条件,并进一步完成关联、统计和分析。

这类查询对传统向量检索方案提出了新的挑战。很多方案通常把向量搜索作为独立服务:应用先调用检索系统得到结果,再把结果交给数据库或分析引擎继续处理。随着数据规模扩大,数据搬运、结果拼接和多套系统之间的协同都会增加额外开销。

Doris 与 Lance 的结合提供了一种不同方式:让 Lance 负责多模态数据存储和向量、全文索引,让 Doris 负责查询规划、分布式执行以及后续 SQL 分析。用户可以直接查询已有 Lance 数据集,在一次 SQL 中完成条件过滤、向量检索、关联、聚合和排序。

为了验证这种方式在大规模场景下的效果,本文使用真实智能驾驶数据进行了测试。在 10 亿规模数据上执行“向量检索+四条件过滤”查询时,Doris + Lance 用时 2.32 秒,Ray + pylance 用时 25.228 秒,后者耗时约为前者的 10.87 倍。测试条件为 Top-K 20,000、召回率 95%、开启缓存、无并发。(完整测试详见后文)

要理解这些性能差异,需要先了解 Doris 如何读取 Lance 数据、如何规划检索任务,以及向量检索结果如何继续参与 SQL 查询。下面先介绍 Doris 与 Lance 的整体架构。

一、整体架构

要让 Doris 直接查询 Lance 数据,首先需要理解两者在查询链路中的职责划分,以及一次查询如何从数据读取进入 SQL 执行流程。

一个 Lance 数据集包含数据文件、数据版本信息、数据分片(Fragment)和索引。Doris 会读取这些信息,再决定如何执行查询。其中,FE 负责规划任务,BE 负责读取数据和执行检索。检索结果可以直接交给 Doris 的其他算子,继续做关联和聚合。

https://ucc.alicdn.com/4cgoqufdwizu4/developer-article1771368/20261015/f2c489c8830446cda02330b8afb19499.png

Doris 提供两种 Catalog 接入方式:Filesystem Catalog 通过目录查找数据集,REST Catalog 通过 Lance Namespace 服务查找数据集。底层数据可以放在本地文件系统、S3 兼容对象存储或 OSS 中。临时查询时,也可以使用支持 Lance 格式的文件表值函数(TVF)直接访问数据集。

Doris 通过 vector_search() 提供向量检索,通过 full_text_search() 使用 Lance 全文索引(FTS)。全文检索支持匹配任一关键词(Match OR)、全部关键词(Match AND)和短语(Phrase)。短语查询要求索引保存词的位置;默认的严格覆盖模式要求当前数据版本中的所有分片都有索引,缺少索引的分片不会自动补做 Flat Search。两种检索入口都能接入后续 SQL 分析;如果需要合并向量与文本排名,需要明确设计结果合并和打分规则。

一条查询主要经过三个步骤:

  1. 规划任务。FE 读取表结构、数据版本、分片列表和索引覆盖范围,确定列类型、需要读取的列,以及任务如何拆分。一次查询使用固定的数据版本。

  2. 执行读取。BE 通过 lance-c 调用 Lance,读取 Arrow 格式的数据,再转换成 Doris 内部使用的 Block,交给后续算子处理。

  3. 继续分析。检索结果可以用于关联(Join)、聚合、排序和分页,也可以与 Doris 内表或其他 Catalog 中的数据一起查询。

这样,检索和后续分析就可以在 SQL 中完成。应用无需先取出 Lance 的结果,再另写一套关联和统计逻辑。

二、并行检索

架构确定了查询链路后,下一步的问题是:如何让大规模数据上的向量检索充分利用集群资源。

要让多个 BE 一起检索,首先要把任务分好。如果任务划分不合理,多个任务可能重复读取同一段索引;如果任务太少,又难以充分利用多个 BE。

Doris 按 Lance 的物理索引段拆分检索任务。索引段是索引的一部分,Fragment 是数据分片,两者的划分方式不同:一个索引段可以覆盖多个 Fragment。Doris 会读取它们的对应关系,再安排扫描任务。

https://ucc.alicdn.com/4cgoqufdwizu4/developer-article1771368/20261015/be775f61da644f0fbdd1650455ea9b35.png

执行向量检索时,FE 先找到与查询列、距离计算方式匹配的索引,再把索引段分配给 BE 并行检索。对于当前数据版本中尚未建好索引的分片,Doris 会安排 Flat Search,也就是直接扫描数据来搜索。这部分结果也会参与最后的合并。

各个任务返回候选结果后,Doris 会统一排序,选出全局 Top-K,即候选中排名最靠前的 K 条记录。因此,已有索引的数据可以走索引检索,未被索引覆盖的数据也能参与查询。向量检索使用近似最近邻搜索(ANN)时,召回率仍取决于索引类型和搜索参数。

普通的条件查询也能利用索引。例如,部分等值、范围、IN 和数组标签匹配条件,可以使用 Lance 的 BTree、Bitmap 或 LabelList 索引。满足条件时,Doris 同样按索引段组织扫描,并扫描未被索引覆盖的数据。能否使用索引,取决于具体条件和索引类型。

索引分段会影响并行效果。分段合理,多个 BE 就能分担工作;分段过细,则会增加任务调度、索引打开和结果合并的开销。实际配置时,需要结合数据分布、BE 数量和查询并发来选择。

三、检索前过滤

并行能够提高计算资源利用率,但如果搜索范围本身过大,仍然需要处理大量无关数据。因此,对于带业务条件的向量检索,过滤发生的时机会直接影响查询效率。

带条件的向量检索,关键在于过滤发生的时间。例如,只查某种车型时,可以先限定车型,再搜索相似记录。如果先找出相似记录、再删除车型不符的结果,就可能得不到足够多的结果。

Doris 的 vector_search() 和 full_text_search() 用 filter 指定过滤条件,用 prefilter 控制何时过滤。默认情况下,prefilter 是 false。需要先过滤再检索时,应明确设置 "prefilter"="true"。

https://ucc.alicdn.com/4cgoqufdwizu4/developer-article1771368/20261015/7fdfe72e88824375b04618c703822262.png

下面的 SQL 演示如何在指定车型和区域内搜索。示例使用四维向量,返回 Top-20;后文性能测试的 Top-K 为 20,000。表名、列名和值均为演示数据,实际使用时,向量维度和距离计算方式 metric 应与数据及索引匹配。

SELECT scene_id, scene_text, resource_uri, _distance
FROM vector_search(
    "table" = "lance_demo.autodrive.scene_samples",
    "column" = "embedding",
    "query_vector" = "[0.12, 0.34, 0.56, 0.78]",
    "top_k" = "20",
    "metric" = "cosine",
    "filter" = "vehicle_type = 'sedan' AND region_code = 'zone_a'",
    "prefilter" = "true",
    "use_index" = "true"
)
ORDER BY _distance ASC, scene_id;

设置 prefilter=true 后,Lance 会先应用函数中的过滤条件,再选择检索候选。如果条件能用上标量索引,就可以通过索引缩小搜索范围;否则,仍可能需要扫描数据来判断条件。过滤能节省多少工作,取决于索引是否可用,以及能排除多少数据。

默认的 prefilter=false 会先选出候选,再应用函数中的 filter。写在函数外层的 SQL WHERE 则由 Doris 继续过滤返回结果。这两种方式都可能删掉已经找到的记录,使最终结果少于 K 条。

对于普通 Lance 扫描,Doris 也能把支持的 SQL 过滤条件交给 Lance 执行,尽早减少读取的数据。Join 过程中产生的部分 Runtime Filter(运行时过滤条件),也可以转换成 IN 或范围条件交给 Lance。这取决于条件和数据类型是否兼容;使用检索函数时,仍需通过 prefilter 明确控制过滤顺序。

四、按需读列

除了搜索范围,数据读取方式也会影响查询性能。向量检索通常只需要计算距离和排序,但最终返回结果时又需要展示大量文本和属性信息。如果这些列过早读取,会造成额外的数据访问成本。

检索结果往往还要展示文本、标签和资源路径。如果每个任务一开始就读取这些列,很多数据会在 Top-K 排序后被丢弃,白白增加读取和传输的开销。

Doris 可以把符合条件的向量检索和全文检索分成两次读取:先选结果,再补读展示列。

https://ucc.alicdn.com/4cgoqufdwizu4/developer-article1771368/20261015/39c979e56063462c9c42507274a94472.png

第一次读取检索、过滤和计算必需的数据,返回行号、距离或分数,以及后续计算需要的列。等 Doris 选出全局 Top-K 后,第二次再按行号读取这些记录的其他展示列。

这样,最终未入选的记录就可以少读、少传一些列。查询仍会读取检索和过滤所需的数据,节省的是可以推迟到最后读取的部分。返回记录较少、每条记录附带的文本或属性较多时,这项优化尤其有用。

两次读取使用同一个数据版本,保证先检索到的记录与后面补读的内容一致。Doris 还支持按版本、时间或命名引用选择 Lance 快照,方便重复查询同一版本的数据。

五、缓存与诊断

前面的优化主要减少单次查询需要处理的数据量,而缓存进一步减少重复查询中的固定开销。

连续查询同一个数据集时,往往会反复访问相同的索引和文件。缓存可以减少重复加载索引、解析元数据,以及从对象存储读取数据的开销。

Doris 在每个 BE 内共享 Lance Session。普通扫描、向量检索、全文检索和按行号补读数据,都可以复用其中相应的缓存。

https://ucc.alicdn.com/4cgoqufdwizu4/developer-article1771368/20261015/1aa440d5bd5e4a529b37e1c08ecbb31a.png

每个 BE 分别管理自己的缓存,BE 之间不共享缓存池。缓存容量也只是内存使用的一部分:扫描任务、数据预读和排序等操作还会占用额外内存。

查询慢在哪里,可以通过 EXPLAIN、Query Profile 和 BE 指标来查看。执行计划能帮助检查任务划分;Profile 可以进一步查看打开数据集、加载索引、远端读取、格式转换和补读列等环节的耗时。索引和元数据缓存的命中率、占用量是 BE 级别的统计,可能包含多个查询的访问。

排查时,可以先确认查询用了索引还是 Flat Search,再看时间主要花在过滤、数据读取、检索还是补读列上。这样更容易找到需要调整的环节。

六、SQL 分析

向量检索的最终目的通常不是返回几个相似结果,而是基于这些结果继续完成业务分析。因此,检索结果能否直接参与 SQL 执行,是衡量一体化查询能力的重要环节。

向量检索或全文检索返回的结果,可以像表一样参与 SQL 查询。Doris 将检索输出交给后续的关联、聚合和排序算子处理。例如,先从 Lance 中找出相似样本,再关联 Doris 内表中的标签,最后统计这些样本的类别分布。这些操作可以写在一条 SQL 中,由 Doris 执行。

https://ucc.alicdn.com/4cgoqufdwizu4/developer-article1771368/20261015/4a9ba805471e4ae6ba6c5aec0e1017b8.png

下面的示例先检索符合车型和区域条件的 Top-20 样本,再关联 Doris 内表 internal.demo.scene_labels,按场景类别统计数量。假设 Lance 数据集中的 scene_id 唯一,标签表也为每个 scene_id 保存一条记录。表名、字段和值均为演示数据,四维向量和距离计算方式需要按实际数据及索引调整。

WITH candidates AS (
    SELECT scene_id
    FROM vector_search(
        "table" = "lance_demo.autodrive.scene_samples",
        "column" = "embedding",
        "query_vector" = "[0.12, 0.34, 0.56, 0.78]",
        "top_k" = "20",
        "metric" = "cosine",
        "filter" = "vehicle_type = 'sedan' AND region_code = 'zone_a'",
        "prefilter" = "true",
        "use_index" = "true"
    )
    ORDER BY _distance ASC, scene_id
    LIMIT 20
)
SELECT
    COALESCE(l.scene_type, '未分类') AS scene_type,
    COUNT(*) AS sample_count
FROM candidates c
LEFT JOIN internal.demo.scene_labels l
    ON c.scene_id = l.scene_id
GROUP BY COALESCE(l.scene_type, '未分类')
ORDER BY sample_count DESC, scene_type;

这条 SQL 分三步执行:candidates 定义检索结果,LEFT JOIN 按样本 ID 补充类别,GROUP BY 统计各类样本的数量。没有匹配标签或类别为空的样本归入“未分类”。应用直接获得统计结果,无需先取回样本,再逐条查标签和计数。

这里统计的是本次返回的 Top-K 样本,反映这批相似样本的类别分布。如果要统计整个数据集,应直接扫描 Lance 表并聚合。示例中的车型和区域条件放在检索函数内,确保在选择候选时就限定搜索范围。

七、性能对比

前面的章节介绍了 Doris + Lance 在查询执行中的几个关键机制:并行检索提高资源利用率,提前过滤减少搜索范围,按需读列降低数据读取成本,缓存减少重复访问开销。下面通过实际测试,观察这些机制组合后的查询效果。

下面是一组来自真实智能驾驶场景的测试结果。

测试对比 Doris + Lance 和 Ray + pylance,数据规模分别为 1 亿、5 亿和 10 亿。查询包括纯向量检索,以及叠加设备、时间、车型、地理和四项组合条件的检索,共六类。

测试条件为 Top-K 20,000、召回率 95%、开启缓存、无并发,耗时单位为秒。Ray 在 1 亿规模使用 4 个 actor,在 5 亿和 10 亿规模使用 16 个 actor。开启缓存不代表每次查询都命中缓存。现有记录未提供双方硬件配置、Doris BE 数量和耗时统计方式,以下结果仅用于比较本次测试的查询耗时。

10 亿规模

https://ucc.alicdn.com/4cgoqufdwizu4/developer-article1771368/20261015/192c022c937e47a1a4c6d286d861183a.png

https://ucc.alicdn.com/4cgoqufdwizu4/developer-article1771368/20261015/74120367a2a74b2abae1b34d36a742ef.png

10 亿规模下,Doris 在地理过滤和四条件过滤查询中分别用时 1.19 秒、2.32 秒,相比 Ray + pylance,耗时均减少约 90.8%。时间过滤查询从 6.044 秒降至 0.73 秒,两者耗时比约为 8.28 倍。

这组结果说明,Doris 在本次“向量检索+条件过滤”测试中表现较好。前文介绍的索引规划、提前过滤、并行检索和按需读列,共同组成了这类查询的执行过程。由于测试没有逐项关闭这些优化,无法单独计算每项优化的贡献。

全部测试结果

https://ucc.alicdn.com/4cgoqufdwizu4/developer-article1771368/20261015/6ffb9e8700d7453da30a9b9e8ec81c35.png

https://ucc.alicdn.com/4cgoqufdwizu4/developer-article1771368/20261015/b09c920205d04eb89569bba4652533ff.png

文中“耗时比”按 Ray + pylance 耗时除以 Doris + Lance 耗时计算,大于 1 表示 Doris 更快。18 组测试中,Doris 有 16 组耗时更低。四条件过滤在 1 亿、5 亿和 10 亿规模下的耗时比分别约为 5.39、7.14 和 10.87 倍。

八、总结

该能力预计可于 10 月底发布的 Apache Doris 4.2 版本中提供体验。Doris 对 Lance 的集成深入到了查询执行的各个环节:按索引段分配任务,让多个 BE 并行检索;提前应用过滤条件,缩小搜索范围;选出 Top-K 后再补读展示列,减少数据读取和传输;通过缓存复用索引、元数据和文件内容。这些机制让 Doris 能够直接利用已有的 Lance 数据和索引,完成检索与分析。

在本文的测试条件下,Doris + Lance 在 18 组查询中有 16 组耗时更低。10 亿规模的“向量检索+四条件过滤”用时 2.32 秒,Ray + pylance 用时 25.228 秒。这组结果体现了 Doris 处理大规模向量检索与条件过滤组合查询的能力,实际收益仍需结合数据、索引和部署配置评估。

对于社区用户,这意味着可以继续使用 Lance 存储多模态数据,同时通过 Doris 的 SQL 接口完成检索、关联和统计。已有的 Lance 数据集由此可以直接服务于样本筛选、数据探索和业务分析,减少应用侧的数据搬运与结果处理工作。

目录
相关文章
|
24天前
|
人工智能 JSON API
全网刷屏的 Jev 模型正式开放!一手实战测评 + 保姆级教程
全网爆火的 Jev 模型是什么?有什么用?怎么使用?怎么接入 AI 编程工具?效果真的好么?傻子可懂的 Jev 保姆级实战教程 + 项目实战测评来啦
9478 31
|
1天前
|
云安全 人工智能 运维
当攻击全面Agent化,你的安全防御能否跟上AI Speed?
多起客户侧AK泄露事件应急的真实观察
1154 0
|
10天前
|
存储 人工智能 并行计算
大模型本地部署终端选型方法论:以 Qwen3.8-27B 为例的四档分层完整流程
本文提出一套大模型本地部署终端选型方法论:定约束、定档位、定框架、定参数四步决策法,配合入门、主力、质量、无损四档分层模型。以 Qwen3.8-27B 实测数据为例,逐环节解读显存、带宽、存储、散热、系统、预算等要素,给出面向不同预算的优选方案、决策自查清单与市场观察框架。文末前瞻 AI 笔记本的 CPU+GPU 与统一内存两条路线,论证四步决策法在新品类上的延续性。
|
9天前
|
人工智能 JSON 自然语言处理
2026 年 Jev 决策模型深度拆解:原理解读、实战测评与保姆级落地教程
有一款特殊AI模型在开发者圈子刷屏,它摒弃传统大模型擅长的对话聊天能力,专注做高速结构化决策,它就是TypeSafe AI推出的Jev模型。该模型由ChatGPT共同发明人Diogo Almeida主导研发,定位为**System One Model(系统一模型)**,对标人类大脑快速直觉判断的思维模式,在响应延迟、调用成本、结构化输出稳定性上相比传统生成式大模型有着巨大差异。本文会完整拆解Jev底层原理、三大核心原语能力、适用业务场景,同时提供可直接运行的curl、Python代码示例,并且结合多组实测数据,客观分析模型优势与能力边界,帮助普通开发者和AI应用从业者快速上手落地。
716 1
|
5天前
|
人工智能 JSON 自然语言处理
2026 年 Jev 决策模型全解析:核心原理拆解,性能实战测评与落地部署教程
有一款特殊AI模型在开发者圈子刷屏,它摒弃传统大模型擅长的对话聊天能力,专注做高速结构化决策,它就是TypeSafe AI推出的Jev模型。该模型由ChatGPT共同发明人Diogo Almeida主导研发,定位为System One Model(系统一模型),对标人类大脑快速直觉判断的思维模式,在响应延迟、调用成本、结构化输出稳定性上相比传统生成式大模型有着巨大差异。本文会完整拆解Jev底层原理、三大核心原语能力、适用业务场景,同时提供可直接运行的curl、Python代码示例,并且结合多组实测数据,客观分析模型优势与能力边界,帮助普通开发者和AI应用从业者快速上手落地。
467 0
|
22天前
|
人工智能 测试技术 API
最近全网爆火的 Jev 到底是什么?适合干什么、怎么用,一篇讲透!
Jev是TypeSafe AI推出的“系统一模型”,不生成文本,专做毫秒级结构化决策:Choice(多选)、Score(打分)、Noul(是非概率)。响应快193倍、成本低444倍,适合工单路由、内容审核、测试定级等高频判断场景。
2545 4
最近全网爆火的 Jev 到底是什么?适合干什么、怎么用,一篇讲透!
|
4天前
|
存储 缓存 测试技术
QWT 3D 模块重构记:旧渲染管线改进介绍及实时瀑布图示例
QWT 3D模块完成重大重构:解耦窗口与图形(Plot+Item),摒弃OpenGL 1.x固定管线,迁至Core Profile着色器渲染;支持多图元同场景叠加,并以实时3D瀑布图验证——滑动窗口、固定色域、64帧×256点达61fps。兼容Qt 5.12+/6,LGPL协议。
176 120
|
16天前
|
Windows
【保姆级】.NET Framework 3.5离线安装教程(2026最新实测)
.NET Framework 3.5是微软经典运行库,专为兼容老软件、老游戏设计。Win7自带,Win10/11需手动启用(在线或离线安装)。它与4.x系列并存不冲突,缺它会导致“找不到组件”报错。本文详解两种安装方式及常见问题解决,小白也能轻松上手。(239字)
2076 0

热门文章

最新文章