游乐游手机版
首页/数据库/文章详情

Agent场景动态JSON性能详细对比拆解:Doris比ClickHouse快7倍,比ES快2倍

时间:2026-07-19 09:43
在人工智能代理日志场景中,ApacheDoris处理动态JSON查询的平均延迟比ClickHouse快7 4倍、比Elasticsearch快2 4倍,存储占用仅为后者的三分之一。Doris通过Variant变体将动态字段转为列式存储的子列,实现了高效聚合与过滤,性能显著优于其他系统。

AI Agent 的日志正在变得越来越复杂。过去日志通常只有时间、级别和消息,但现在一次 Agent 调用可能包含模型参数、工具调用、检索结果、Prompt 版本、用户上下文等大量动态字段。这些字段很难提前设计 schema,于是 JSON 成为了最自然的数据承载方式

那么问题来了:当 payload(也就是结构经常变化、字段无法提前固定的 JSON 数据)从几十个字段扩展到几百、几千个字段时,数据库还能不能像查询普通列一样,高效分析这些动态 JSON?

上一篇我们讨论了 AgentLogsBench 的设计目标和综合测试结果。不过 Benchmark 只是表象,更值得追问的是:

为什么同样都支持 JSON,不同数据库在 Agent 日志场景下的性能差异会如此明显

这一篇,我们把视角进一步下沉,聚焦 AgentLogsBench 中与动态 JSON / Variant 最相关的一组查询,看看当 payload 持续变宽、字段不断演进时,系统到底应该如何存储和执行 JSON Path 查询。

Agent 日志为什么会放大 JSON 性能差异

关于 AgentLogsBench 的整体数据集、查询模型和测试方法,上一篇已经做过介绍,这里不再重复展开。本文只聚焦其中一个关键点:Agent 日志中的动态 payload。

在一条 agent trace 中,稳定字段适合提升为列,用于检索、过滤和聚合;而变化更快、来源更复杂的字段,则会不断进入 payload。例如模型返回状态、工具执行结果、OpenTelemetry 状态码、Prompt template、workflow variant、request key 等。

一行 observation 大致长这样:

 复制代码{
  "event_time": "2026-04-01T12:00:00Z",
  "trace_id": "trace_000001",
  ...
  "payload": {
    "provider": {
      "stop_reason": "tool_use",
      "cache_hit": false
    },
    "tool_result": {
      "stderr": "unable to open ...",
      "exit_code": 1
    },
    "otel": {
      "status_code": "ERROR"
    }
  }
}

JSON分析的难点在于:

当 schema 持续变化时,系统还能不能像访问结构化列一样,对这些动态字段做低延迟过滤、聚合、全文检索和成本分析

与上一篇介绍的数据模型一致,AgentLogsBench 始终要求所有系统在同一张 agent_observations 表上完成查询,不允许通过预先 flatten JSON、拆分辅助表或预定义所有字段来规避动态 schema 的挑战。

因此,测试的关键在于:

谁能在动态字段持续增长的情况下,同时完成检索、过滤、聚合和分析

这正好贴近 Agent observability 的真实问题。字段会随着模型、工具、框架、客户配置和 workflow 演进而不断变化,但排障和分析仍然要求低延迟响应。

先看测试结果

查询延迟:Doris 的优势主要在动态字段分析

上一篇已经介绍了综合排行榜。这里只拆开与 Variant / JSON Path 最相关的一组查询。

为了便于阅读,主表只保留关键对照:Apache Doris、ClickHouse、Elasticsearch、OpenSearch。完整公开结果仍包含 DuckDB 和 PostgreSQL。

根据表格可以得出以下结论:

  • Elasticsearch / OpenSearch 在全文检索相关查询上依然很强,Q19 甚至可以打平 Doris。
  • ClickHouse 存储压缩很好,但在动态 payload 查询上延迟明显更高。
  • Doris 的优势主要体现在 Q10、Q12、Q16、Q20 这类动态字段聚合、rollup 和低基数过滤上。
  • 在本文关注的 JSON Path 分析查询集合中(Q07、Q10、Q12、Q16、Q17、Q18、Q20),ClickHouse 的平均延迟约为 Doris 的 7.4 倍,Elasticsearch / OpenSearch 约为 Doris 的 2.4 倍。

这说明,在 Agent observability 里,搜索只是第一步。找到异常记录之后,开发者通常还要继续按 payload 字段过滤、统计错误分布、比较不同 prompt、模型版本、发布环和客户等级。

因此,决定整体体验的不是单次搜索速度,而是搜索之后还能否低成本完成动态字段查询、聚合和关联分析。Doris 的优势也主要体现在这里。

存储空间:Doris 在搜索能力与存储成本之间找到了平衡

存储结果也反映了不同系统的取舍。

  • ClickHouse 最省空间,符合它在列式压缩上的一向优势。
  • Elasticsearch / OpenSearch 存储占用明显更高,因为需要为倒排索引、词项字典、短语查询等维护额外结构。
  • Doris 的取舍更接近混合负载系统:它同时支持全文检索和动态 payload 查询,但在 100M 数据规模下,存储占用只有 Elasticsearch / OpenSearch 的大约三分之一,同时接近 ClickHouse 的量级。

这也是 Doris 综合表现较好的原因之一:在列式分析系统内部同时提供了 Variant、倒排索引、SQL 聚合和缓存能力

Doris Variant:把动态 JSON 纳入列式执行链路

从 JSON Path 到列式 subcolumns

Doris VARIANT 的关键不是支持 JSON 语法,而是把常用 JSON Path 变成了内部列式 subcolumns。

写入时,Doris 会对 JSON Path 做解析、类型推断和 subcolumnization。查询时,用户仍然写 JSON Path:

 复制代码SELECT
    CAST(payload['attr']['release_ring'] AS STRING) AS release_ring,
    CAST(payload['attr']['customer_tier'] AS STRING) AS customer_tier,
    count(*) AS observations,
    a vg(latency_ms) AS a vg_latency_ms,
    sum(total_cost) AS total_cost
FROM agent_observations
WHERE type IN ('GENERATION', 'TOOL', 'RETRIEVAL')
GROUP BY
    CAST(payload['attr']['release_ring'] AS STRING),
    CAST(payload['attr']['customer_tier'] AS STRING)
ORDER BY observations DESC
LIMIT 50;

但执行器会优先命中内部的列式存储。

这也是 Q12 这类查询快的原因:它表面上是在读 payload,实际是在读若干 typed subcolumns,而且可以做列裁剪、向量化执行、局部字典/压缩和索引过滤。

不妨把这个过程想象成:传统 JSON 查询像是在一个大文件里不断翻找字段,而 Variant 会把经常访问的 JSON 路径拆出来,让它们拥有类似普通数据列一样的查询能力。

宽 JSON 的真正瓶颈:热点路径和长尾字段混在一起

Agent logs 的 payload 会越来越宽。有些路径会变成热点,例如:

  • payload.attr.release_ring
  • payload.attr.customer_tier
  • payload.provider.cache_hit
  • payload.provider.stop_reason

但更多字段会非常长尾,来自不同模型、工具、插件、客户配置和 workflow。

如果系统对所有路径一视同仁,就会出现一个问题:明明只查几个热点字段,却被大量 metadata、稀疏列和长尾字段拖慢。

Doris 的处理方式是:高频路径列式化,低频路径进入 sparse columns 或 DOC encoding,并且在宽列场景推荐使用 Storage Format V3。

当 VARIANT 生成大量动态 subcolumns 时,Storage Format V3 可以将列元数据从 Segment Footer 中解耦出来,从而加快文件打开速度,降低内存开销,使得热点字段像普通列一样实现低延迟访问。

其他系统的取舍

DuckDB / Parquet Variant:开放格式优势明显,但在线分析链路仍有短板

Parquet Variant / DuckDB Variant 的价值在于开放格式。它们把半结构化数据从 JSON string 推向 typed binary representation,并支持把高频字段 shred 成强类型列。

这对于湖仓交换、本地分析和跨引擎读写来说非常合适。

但在 AgentLogsBench 的 100M 主测试中,DuckDB 在 JSON Path 查询上的表现与 Doris 存在差距(DuckDB 在核心查询中的延迟大约在 282.798s 到 7414.692s 之间,而 Doris 为 0.032s 到 1.497s)。原因在于,开放文件格式主要解决的是“怎么存得更通用”,而 Doris Variant 解决的是:在线分析系统如何把动态 JSON 纳入列式存储、索引、compaction 和向量化执行链路。

Elasticsearch / OpenSearch:搜索能力强劲,但动态聚合成本偏高

Elasticsearch / OpenSearch 的强项是搜索。Q17 这类高基数 filter、Q19 这类 text token + rollup 查询,它们表现都很好。

但 dynamic mapping 对字段爆炸比较敏感。Agent logs 的 payload.attr.*payload.tool_result.*payload.otel.*、框架私有字段和插件字段天然就是长尾的。如果全部映射成可聚合字段,mapping、doc values、heap 和 segment metadata 的成本都会上升。

因此,搜索能力仍然很强,但搜索之后的多维聚合、动态字段分析和低成本长期存储,会变得更复杂。

ClickHouse JSON:压缩优势明显,但长尾路径查询仍有代价

ClickHouse 的 JSON 类型已经有 subcolumns 能力,也在持续优化 shared data。但当动态路径超过限制后,长尾路径会进入 shared data。查询这些路径时,往往需要额外读取和过滤。

ClickHouse v25.8 引入了 bucketed / advanced shared data serialization,让系统可以更精细地跳到特定 path 的数据,避免读取过多无关 substreams。但这类设计也有代价:读取完整 JSON 或 merge 可能会变慢,因此需要保存额外原始格式副本来平衡兼容性和效率,这也会带来存储开销。

在 100M 公开结果中,ClickHouse 的存储确实更低,但 Q10、Q12、Q16、Q17、Q20 等动态 payload 查询明显慢于 Doris;Q19 更是 30.816s 对比 Doris 的 1.013s。

一张表总结:不同系统如何理解 JSON

Doris 把动态 JSON 收进了数据库自己的列式、索引和文件格式体系;其他系统更多是在搜索索引、开放文件格式或行存 JSON 文档的边界内进行优化。

结束语

总结来看,AgentLogsBench 反映的并不是单个 JSON 函数的性能差异,而是不同系统对动态 JSON 的处理方式差异。

在 Agent 可观测性场景中,payload 会持续变宽,字段会不断演进,但查询热点往往集中在少数业务路径上。系统能否把这些动态路径纳入列式存储、索引、压缩和向量化执行链路,决定了搜索之后的分析体验。

Doris 的优势正来源于此:它通过 Variant 将动态字段转化为可裁剪、可索引、可聚合的列式结构。对于 AI Agent 日志、事件分析和 RAG / Agent Trace 分析这类负载,这种能力会越来越关键。

参考资料

  • AgentLogsBench README / 公开结果:benchmark 设计、100M shard、median latency 和结果文件说明。
  • Apache Doris VARIANT 文档:Subcolumnization、路径推断和半结构化列设计。
  • Apache Doris VARIANT Workload Guide:Storage Format V3、sparse columns、DOC mode 和宽 JSON 建议。
  • Apache Doris Inverted Index 文档:倒排索引和 V3 index storage format。
  • Elasticsearch Mapping Explosion 文档:dynamic mapping 下字段爆炸的风险。
  • Elasticsearch text field / fielddata 文档:text 字段聚合、排序和 fielddata 的代价。
  • ClickHouse JSON Data Type 文档:ClickHouse JSON subcolumns、dynamic paths 和 shared data 背景。
  • ClickHouse JSON shared data serialization 博客:v25.8 bucketed / advanced shared data serialization 的改进与取舍。
  • Apache Parquet Variant 介绍:Parquet Variant logical type、metadata/value 编码和 shredding。
  • DuckDB Variant 类型文档:DuckDB 对 Variant 和 Parquet Variant 的读写支持。
来源:https://juejin.cn/post/7660689656081645618
上一篇MySQL生产环境定位全表扫描慢事务的排查方法 下一篇MySQL大数据量BETWEEN范围查询性能优化方法
本站内容用于信息整理与展示,如有侵权或内容问题请及时联系处理。

相关推荐

补充同频道和同主题内容,方便继续浏览更多相关内容。

同类最新

继续查看同栏目最近更新的文章。

更多
Win/Linux Navicat数据模型同步,导出ndm文件用Git版本管理
数据库 · 2026-07-19

Win/Linux Navicat数据模型同步,导出ndm文件用Git版本管理

Navicat的 ndm文件是二进制黑箱,跨平台无法兼容。应导出为SQL和XMI(UTF-8无BOM)文本文件,通过Git管理。仓库路径需统一小写命名,禁止直接保存模型,必须走导出提交同步重新导入闭环。Linux导入时注意编码和覆盖选项。

跨库SQL JOIN字符集校验规则不同导致匹配失败的排查方法
数据库 · 2026-07-19

跨库SQL JOIN字符集校验规则不同导致匹配失败的排查方法

跨库SQLJOIN失败多因字段排序规则(COLLATION)不兼容,即便字符集相同。需通过INFORMATION_SCHEMA查询字段COLLATION,并检查连接层设置。临时修复可在JOIN条件中显式使用COLLATE对齐;根本解决需ALTERTABLE同时修改CHARACTERSET和COLLATE。

利用AWR报告诊断表空间碎片对扫描性能的影响
数据库 · 2026-07-19

利用AWR报告诊断表空间碎片对扫描性能的影响

通过AWR报告中dbfilesequentialread等待异常、物理读请求次数增幅远超读块数、以及SQL执行计划从索引扫描退化为全表扫描这三类信号交叉验证,可判断表空间碎片是否拖慢扫描性能,避免误判。

MySQL第三方审计系统只读系统视图权限配置方法
数据库 · 2026-07-19

MySQL第三方审计系统只读系统视图权限配置方法

为审计账号配置MySQL只读权限时,performance_schema必须逐表显式授权,不可使用* *或库级批量授权;认证插件必须指定mysql_native_password;无法通过视图封装,必须直接授权原始表。这是审计账号配置的关键注意事项,必须严格遵守,并遵循最小权限原则。

Navicat团队项目自定义图标背景色设置方法
数据库 · 2026-07-19

Navicat团队项目自定义图标背景色设置方法

Navicat中设置团队项目图标背景色实为两个独立配置:模型图节点颜色需手动修改navicat ini文件并完全重启;SQL编辑器及主窗口背景色通过主题设置。版本一致、配置路径准确、激活ERD模式是效果一致的关键。修改后必须彻底退出程序。