Agent 场景动态 JSON 性能拆解:Apache Doris 比 ClickHouse 快 7 倍、比 Elasticsearch 快 2 倍

📅 2026/7/11 7:37:18
Agent 场景动态 JSON 性能拆解:Apache Doris 比 ClickHouse 快 7 倍、比 Elasticsearch 快 2 倍
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 observabilityAgent 可观测性 的真实问题。字段会随着模型、工具、框架、客户配置和 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、Q20ClickHouse 的平均延迟约为 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 到列式 subcolumnsDoris VARIANT 的关键不是支持 JSON 语法而是把常用 JSON Path 变成内部列式 subcolumns。写入时Doris 会对 JSON Path 做解析、类型推断和 subcolumnization。查询时用户仍然写 JSON PathSELECT CAST(payload[attr][release_ring] AS STRING) AS release_ring, CAST(payload[attr][customer_tier] AS STRING) AS customer_tier, count(*) AS observations, avg(latency_ms) AS avg_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_ringpayload.attr.customer_tierpayload.provider.cache_hitpayload.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 查询上没有接近 DorisDuckDB 在核心查询中的延迟大约在 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 查询明显慢于 DorisQ19 更是 30.816s vs Doris 1.013s。一张表总结不同系统如何理解 JSONDoris 把动态 JSON 收进了数据库自己的列式、索引和文件格式体系其他系统更多是在搜索索引、开放文件格式或行存 JSON 文档的边界内优化。结束语总结来看AgentLogsBench 反映的并不是单个 JSON 函数的性能差异而是不同系统对动态 JSON 的处理方式差异。在 Agent 可观测性场景中payload 会持续变宽字段会不断演进但查询热点往往集中在少数业务路径上。系统能否把这些动态路径纳入列式存储、索引、压缩和向量化执行链路决定了搜索之后的分析体验。Doris 的优势也正来自这里它通过 Variant 将动态字段转化为可裁剪、可索引、可聚合的列式结构。对于 AI Agent 日志、事件分析和 RAG / Agent Trace 分析这类负载这种能力会越来越关键。如果你想要以全托管的方式运行 Apache Doris可以选择 SelectDB它提供了驱动 benchmark 结果的同一套 VARIANT、倒排索引和缓存能力。在这一能力之上如果进一步将其封装为面向 Agent 的可观测与评估平台—— Litefuse可以在底层数据能力之上直接构建 trace 管理、评估体系、查询分析与多租户可观测的一体化平台。参考资料AgentLogsBench README / 公开结果benchmark 设计、100M shard、median latency 和结果文件说明。Apache Doris VARIANT 文档Subcolumnization、路径推断和半结构化列设计。Apache Doris VARIANT Workload GuideStorage 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 的读写支持。