新闻详情

新闻详情

首页 / 资讯中心 / 详情

Databend 查询优化器 Replay 测试数据体系:YAML 用例、统计注入与双 Runner 运行机制

发布时间:2026/9/16 16:25:21来源:尧图网络
Databend 查询优化器 Replay 测试数据体系:YAML 用例、统计注入与双 Runner 运行机制
Databend 查询优化器 Replay 测试数据体系YAML 用例、统计注入与双 Runner 运行机制【免费下载链接】databendData Agent Ready Warehouse : One for Analytics, Search, AI, Python Sandbox. — rebuilt from scratch. Unified architecture on your S3.项目地址: https://gitcode.com/GitHub_Trending/da/databendDatabend 的查询优化器在 SQL 语义绑定、逻辑计划优化与物理计划生成三个阶段都存在大量回归风险因此需要一套可脱离真实集群、可复现、可对比的重放Replay测试体系。本文以仓库中的 Optimizer Replay Data 说明文档 为主线系统讲解 Databend 如何通过cases/tables/statistics/results四类共享数据文件组织优化器测试深入剖析 YAML 测试用例的完整字段、统计信息的注入原理并给出新增与更新测试用例的完整实操流程。读完本文你将掌握 Databend 优化器 Replay 测试从写一条 SQL 用例到生成三份黄金结果文件的全链路工作方式。一、Replay 测试体系解决的问题Databend 优化器测试的核心诉求是在无真实数据、无真实存储引擎的情况下验证优化器对任意 SQL 生成的执行计划是否符合预期。为此优化器测试引入了Replay概念——把真实数据库中的元信息表结构、统计信息行数、大小、NDV、直方图预先导出为共享数据文件测试运行时将这些信息注入内存中的假表Fake Table从而让优化器在一个仿真数据库上工作。这份共享数据集的权威定义位于 src/query/sql/test-support/data/README.md它是下面两个 Replay 型测试运行器的唯一数据源运行器所在测试文件覆盖范围SQL 侧轻量 Replaysrc/query/sql/tests/it/planner.rsSQL 绑定bind 逻辑计划优化optimizeService 侧 Replaysrc/query/service/tests/it/sql/planner/optimizer/optimizer_test.rs绑定 优化 物理执行计划含集群 Exchange 分发需要特别说明的是这份共享数据集并不包含全部 SQL 侧黄金文件。模块局部的黄金文件如轻量级语义测试、轻量级优化器测试的结果存放在各自测试旁的目录下例如src/query/sql/tests/it/semantic/binder.txtsrc/query/sql/tests/it/optimizer/eager_aggregation.txt而test-support/data只保存跨测试共享的 Replay 数据集。二、数据目录结构总览test-support/data目录按测试用例、表定义、统计信息、追踪夹具、结果五类职责组织实际仓库在此基础上还包含eager_aggregation/与regressions/等分层子目录见 data 目录实际内容src/query/sql/test-support/data ├── tables/ # SQL 表定义 │ ├── basic/ # 基础表定义 │ ├── eager_aggregation/ # 急切聚合专用表 │ ├── obfuscated/ # 脱敏表定义 │ ├── regressions/ # 回归问题专用表 │ └── tpcds/ # TPC-DS 全套表定义24 张 ├── statistics/ # 统计信息文件 │ ├── obfuscated/ # 脱敏统计 │ └── tpcds/ # TPC-DS 统计如 tpcds_100g.yaml ├── cases/ # YAML 测试用例定义 │ ├── basic/ │ ├── eager_aggregation/ │ ├── obfuscated/ │ ├── regressions/ │ └── tpcds/ ├── statistics_trace/ # StatisticsTrace 重放夹具 │ ├── sql/ # 从 trace JSON 重放的 SQL 语句 │ └── traces/ # StatisticsTrace JSON 载荷 └── results/ # 测试结果文件自动生成 ├── basic/ ├── eager_aggregation/ ├── obfuscated/ ├── regressions/ └── tpcds/框架支持任意层级的子目录嵌套collect_files_recursive会递归扫描便于按业务域basic / tpcds / obfuscated / regressions / eager_aggregation分类组织测试用例、表和结果。用例加载后按名称排序执行保证跨平台结果稳定见 optimizer/mod.rs 中的TestSuite::load_cases。三、YAML 测试用例格式详解每个测试用例由一个 YAML 文件定义放在cases/的对应子目录中。文档给出了完整的字段骨架仓库源码TestSpec结构体见 src/query/sql/test-support/src/optimizer/mod.rs与其一一对应。完整格式如下name: Q3 # 测试用例名 description: Test description # 可选用例描述 sql: | # 待测试的 SQL 查询 SELECT ... auto_statistics: false # 是否启用 CollectStatisticsOptimizer默认 false statistics_file: tpcds_100g # 可选引用外部统计文件 # 来自 statistics/ 目录扩展名可选 table_statistics: # 内联表统计可与 statistics_file 合并 table_name: num_rows: 1000 # 总行数 data_size: 102400 # 数据大小字节 data_size_compressed: 51200 # 压缩后数据大小 index_size: 20480 # 索引大小 number_of_blocks: 10 # Block 数量 number_of_segments: 2 # Segment 数量 column_statistics: # 内联列统计可与 statistics_file 合并 table_name.column_name: min: 1990 # 最小值数字或字符串 max: 2000 # 最大值数字或字符串 ndv: 10 # 不同值数量distinct count null_count: 0 # NULL 数量 histogram_statistics: # 可选按 表.列 为键的内联直方图 table_name.column_name: accuracy: true # bucket 的 distinct 数是否为 ANALYZE 的精确事实 buckets: - lower_bound: !Int 1990 # bucket 最小值显式 Datum 标记 upper_bound: !Int 2000 # bucket 最大值显式 Datum 标记 num_values: 1000 # bucket 覆盖的行数 num_distinct: 10 # bucket 覆盖的 distinct 数 good_plan: | # 可选期望的良好执行计划文档性参考 ...各字段的源码对应关系与要点name与sql是必填项其余字段均有#[serde(default)]可省略。statistics_file引用外部文件时框架在statistics/目录下按文件名 stem 匹配load_stats_file支持带数字前缀的文件名如01_tpcds_100g.yaml也支持省略.yaml扩展名。内联统计与外部统计文件通过resolve_stats合并内联在前、文件在后extend同名 key 由文件覆盖内联值二者可组合使用。tables字段见下文表定义把逻辑表名映射到tables/下的 SQL 文件。node_num字段源码TestSpec中为Optionu64用于指定 Service 侧测试的集群节点数用于验证分布式 Exchange 计划。3.1 真实用例示例TPC-DS Q03仓库中 cases/tpcds/Q03.yaml 是一个完整的真实用例——它引用外部 100G 统计文件声明 24 张 TPC-DS 表并附带了优化器期望的good_plan手工阅读用参考非断言依据name: Q03 description: TPC-DS Query 3 optimizer test sql: | SELECT dt.d_year, item.i_brand_id brand_id, item.i_brand brand, SUM(ss_ext_sales_price) AS sum_agg FROM date_dim dt, store_sales, item WHERE dt.d_date_sk store_sales.ss_sold_date_sk AND store_sales.ss_item_sk item.i_item_sk AND item.i_manufact_id 128 AND dt.d_moy 11 GROUP BY dt.d_year, item.i_brand, item.i_brand_id ORDER BY dt.d_year, sum_agg DESC, brand_id LIMIT 100 statistics_file: tpcds/tpcds_100g.yaml good_plan: | Result [output: DT.D_YEAR, ITEM.I_BRAND_ID, ITEM.I_BRAND, SUM(...)] └── SortWithLimit [limit: 100] └── Aggregate [group by: ...] └── InnerJoin [join key: ...] └── ... tables: call_center: tpcds/call_center.sql catalog_page: tpcds/catalog_page.sql # ... 其余 22 张 TPC-DS 表而回归用例则非常精简例如 cases/regressions/20379_non_nullable_reflexive_equality.yaml 只有name、description与sql三个字段——它专门验证非空列的自反等值value value在过滤推断阶段仍应被消除这一特定优化行为不需要任何统计信息。四、外部统计文件与 Datum 标记当多个用例共享同一套统计口径如 TPC-DS 100G时把统计抽到statistics/目录单独维护。仓库中的 statistics/tpcds/tpcds_100g.yaml 给出了完整样例包含table_statistics、column_statistics、histogram_statistics三块table_statistics: catalog_sales: num_rows: 143997065 data_size: 7786861047 number_of_segments: 432 # ... 其他表 column_statistics: catalog_sales.cs_sold_date_sk: min: 2450815 max: 2452921 ndv: 1823 null_count: 0 # ... 其他列 histogram_statistics: catalog_sales.cs_sold_date_sk: accuracy: true buckets: - lower_bound: !Int 2450815 upper_bound: !Int 2452921 num_values: 143997065 num_distinct: 1823这里有两个值得注意的细节!Int标签直方图 bucket 的lower_bound/upper_bound被反序列化为databend_common_statistics::Datum见HistogramBucketStats的lower_bound: Datum字段因此需要显式类型标记。而列统计的min/max则是宽松的serde_json::Value源码to_datum会自动把 JSON 数字解析为 Int64 或 Float64、把 JSON 字符串解析为 String。缺失极值的自动补全build_column_stats中如果 YAML 未提供min/max框架会按列类型调用default_min_datum/default_max_datum补全浮点用 ±F64::MAX、有符号整型用 ±i64::MAX、无符号用 ±u64::MAX、字符串用 0x00 与 0xFFFF 填充避免优化器在比较运算中因缺省极值而做出错误推断。五、统计注入的底层原理Replay 测试的关键一步是把 YAML 中的统计信息贴到绑定后的逻辑计划表扫描节点上。源码中StatsApplier见 src/query/sql/test-support/src/optimizer/mod.rs实现了一个SExprVisitor遍历逻辑计划 S 表达式遇到RelOperator::Scan节点时通过metadata.table(scan.table_index)找到逻辑表若该表在table_statistics中有配置则同时构建列统计与直方图拼装成TableStatistics column_stats histograms注入新的Scan节点并以VisitAction::Replace替换原节点统计注入口径在run_test_case_core中先bind_sql得到原始计划 →apply_stats注入统计 → 格式化输出_raw.txt→optimize_plan得到优化计划 → 输出_optimized.txt→ 若运行器支持物理计划则输出_physical.txt。轻量侧SQL 侧的表与统计是如何无数据库工作的答案是内存中的假目录与假表src/query/sql/test-support/src/lite_context.rs中实现了DummyCatalog一个仅支持get_table的内存 HashMap 目录与FakeTable把TableStatistics、列统计、直方图、TopN、CountMinSketch 通过FakeColumnStatisticsProvider暴露给优化器。LiteTableContext::build_fake_table会把 YAML 中的字段名解析为列 ID 后构造假表configure_for_optimizer_case则先关闭自动物化 CTE再调用configure_optimizer_settings设置固定优化器开关。5.1 固定的优化器测试环境为保证结果可复现configure_optimizer_settingsoptimizer/mod.rs统一固定了以下会话设置设置项值作用enable_dphyp1启用 DPhyp 连接枚举算法max_push_down_limit10000允许下推的 LIMIT 上限enable_optimizer_trace1开启优化器 traceenable_shuffle_sort0关闭 shuffle sortoptimizer_skip_listCollectStatisticsOptimizerauto_statisticsfalse时跳过统计收集优化器为true时清空即启用其中auto_statistics字段正是控制CollectStatisticsOptimizer是否参与默认false跳过直接使用 YAML 提供的统计置true则让优化器自行收集统计后继续优化。5.2 集群形态的模拟LITE_REPLAY_CASE_SPECSplanner.rs为每个轻量用例声明了warehouse_distribution是否按 Warehouse 分布式表处理与default_node_num默认集群节点数用例 YAML 中的node_num可以覆盖默认值。Service 侧测试则在test_optimizer中按case.node_num动态构造 N 个节点的集群optimizer_test.rs从而验证 ExchangeBroadcast/Hash等分布式算子的物理计划。六、表定义tables/ 目录tables/下的每个文件包含一条或多条CREATE TABLE语句。两个运行器使用方式不同轻量运行器解析并注册这些 SQL 到内存 fixtureDummyCatalog中只取元信息不真正建表Service 运行器在真实测试上下文中执行相同 SQL 建表若表已存在则忽略TABLE_ALREADY_EXISTS错误见setup_tables中的错误分支处理测试结束后再由clean_tables统一DROP TABLE。用例通过tables:映射声明依赖见 Q03.yamlresolve_tables会在tables/下递归查找与映射值匹配的 SQL 文件并读入内容。TPC-DS 全套 24 张表位于 tables/tpcds回归用例专用表位于 tables/regressions。七、运行 Replay 测试7.1 运行全部 Service 侧测试cargo test --package databend-query --test it -- sql::planner::optimizer::optimizer_test::test_optimizer --exact --nocapture该命令对应 optimizer_test.rs 中的test_optimizer会依次执行全部子目录用例并为每个用例打印 Testing: case 与通过标记。7.2 运行全部轻量级共享测试cargo test --package databend-common-sql --test it -- planner::test_lite_replay_service_optimizer_cases --exact --nocapture对应 planner.rs 中的test_lite_replay_service_optimizer_cases。它会把共享数据集的用例与LITE_REPLAY_CASE_SPECS白名单按名称匹配后逐个执行——不在白名单中的用例如仅 Service 侧关注的物理计划用例会被跳过。7.3 只运行指定子目录TEST_SUBDIRtpcds cargo test --package databend-query --test it -- sql::planner::optimizer::optimizer_test::test_optimizer --exact --nocapture两个运行器都读取TEST_SUBDIR环境变量std::env::var(TEST_SUBDIR).ok()把搜索范围收窄到cases/subdir及其对应的tables/statistics/results子目录适合快速调试单类用例。八、生成的 Replay 结果文件每个用例执行后在results/对应子目录下最多生成三个黄金文件命名以用例文件 stem 为前缀文件内容{test_name}_raw.txt优化前的原始逻辑计划已注入统计{test_name}_optimized.txt优化后的逻辑计划{test_name}_physical.txt物理执行计划仅当运行器支持物理规划时生成如 Service 侧例如 results/regressions/q17_histogram_join_order_optimized.txt 展示了基于直方图重排连接顺序后的优化计划而 results/regressions/q17_histogram_join_order_physical.txt 展示了含Exchange(Broadcast)/Exchange(Hash)的分布式物理计划。TestSuiteMints会为每个子目录维护独立的Mintgoldenfile 框架确保结果按目录结构镜像保存。九、StatisticsTrace 重放夹具statistics_trace/是专门针对StatisticsTrace统计收集轨迹的重放夹具由成对的 SQL 与 JSON 组成statistics_trace/sql/从 trace JSON 还原出的 SQL 语句如tpch_returned_orders.sql、customer_self_join.sqlstatistics_trace/traces/StatisticsTrace的 JSON 载荷其中按表索引记录table_stats行数、数据/索引大小、Block/Segment 数与字段类型定义见 traces/tpch_returned_orders.json。两种消费方式见 planner.rs 的StatisticsTraceGoldenCase与replay_statistics_trace_caseService 侧 trace 测试用CollectStatisticsOptimizer生成全新的 JSON 载荷与 JSON 夹具逐一比对差值即回归信号SQL 侧黄金测试通过轻量重放 harness 消费同一组 SQL 与 JSON 夹具输出优化计划快照。十、新增 Replay 测试的完整流程要新增一个优化器回归用例按以下五步操作在cases/的合适子目录如basic/、tpcds/、obfuscated/、regressions/下新建 YAML 文件按第三节的格式填写name、sql及所需统计字段若用到新表在tables/对应子目录新增含CREATE TABLE语句的 SQL 文件并在 YAML 的tables:中声明映射若需要共享统计口径在statistics/对应子目录新增统计 YAML并用statistics_file引用运行测试——测试运行器会递归自动发现并执行所有子目录下的全部用例无需注册清单测试结果会自动保存到results/下与用例相同结构的子目录中{stem}_raw.txt、{stem}_optimized.txt物理计划存在时还有{stem}_physical.txt。轻量侧若希望新用例被test_lite_replay_service_optimizer_cases执行还需把用例名加入 planner.rs 的LITE_REPLAY_CASE_SPECS白名单并配置warehouse_distribution与default_node_numService 侧则无需白名单test_optimizer会直接消费全部用例。十一、更新既有测试的黄金文件当优化器行为发生有意变更、期望输出随之改变时携带UPDATE_GOLDENFILES环境变量重新运行测试框架会生成新的结果文件UPDATE_GOLDENFILES1 cargo test --package databend-query --test it -- sql::planner::optimizer::optimizer_test::test_optimizer --exact --nocapture新结果文件自动保存到results/下与用例同结构的子目录仔细 review 变更内容确认与优化器的预期行为一致后提交。这套数据驱动 黄金文件比对的机制配合goldenfile的 Mint 管理让 Databend 在 TPC-DS/TPC-H 复杂查询、直方图驱动连接排序、CTE 物化、急切聚合等优化场景下都能获得稳定、可审查、可追溯的回归保障。小结Databend 的 Optimizer Replay 测试数据体系本质上是一个用 YAML 描述数据库形态、用内存假表承载元信息、用统计注入驱动优化决策、用黄金文件锁定计划输出的闭环。通过本文你可以快速上手阅读 data 目录 README 理解目录约定参考 Q03.yaml 编写新用例借助 tpcds_100g.yaml 复用统计口径最后用TEST_SUBDIR与UPDATE_GOLDENFILES高效迭代你的优化器改动。【免费下载链接】databendData Agent Ready Warehouse : One for Analytics, Search, AI, Python Sandbox. — rebuilt from scratch. Unified architecture on your S3.项目地址: https://gitcode.com/GitHub_Trending/da/databend创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

OpenClaw在CentOS 7上的自动化运维部署指南 2026/9/16 17:04:27

OpenClaw在CentOS 7上的自动化运维部署指南

1. 项目背景与核心价值OpenClaw作为一款开源的自动化运维工具链组件,在Linux服务器管理领域有着独特的应用场景。它主要面向需要批量执行命令、文件分发和任务调度的运维场景,特别适合中小型技术团队在没有成熟运维体系时的过渡方案。我在实际生产环境中…

阅读更多 →
自建月亮慢直播频道:FFmpeg+Nginx实现24小时无人值守直播 2026/9/16 17:04:27

自建月亮慢直播频道:FFmpeg+Nginx实现24小时无人值守直播

凌晨两点十七分,LunaTV的直播间在线人数定格在11人,弹幕里飘过一句“月亮很好看,晚安”。那一刻我盯着监控面板,反而松了一口气——这个频道已经连续稳定播出了71个小时。作为一个没有编导、没有摄影、没有运维的独立创作者&#…

阅读更多 →
Elementor 动态标签实战:为 v4 原子组件(Atomic Widgets)从第三方插件接入动态数据源 2026/9/16 17:04:27

Elementor 动态标签实战:为 v4 原子组件(Atomic Widgets)从第三方插件接入动态数据源

Elementor 动态标签实战:为 v4 原子组件(Atomic Widgets)从第三方插件接入动态数据源 【免费下载链接】elementor The most advanced frontend drag & drop page builder. Create high-end, pixel perfect websites at record speeds. An…

阅读更多 →
Django HTML图像取证系统:DOM哈希与结构化差异比对 2026/9/16 17:04:27

Django HTML图像取证系统:DOM哈希与结构化差异比对

简介:本资源是一套面向本科毕业设计与图像取证初学者的完整Django Web系统实现方案,聚焦数字图像真实性分析与篡改检测技术落地。项目以Python为核心,采用Django构建稳健后端,HTMLCSSJS实现交互式前端界面,MySQL支撑图…

阅读更多 →
不知道要什么风格?Garden Skills 设计方向顾问帮你 3 步锁定设计方向 2026/9/16 17:04:27

不知道要什么风格?Garden Skills 设计方向顾问帮你 3 步锁定设计方向

不知道要什么风格?Garden Skills 设计方向顾问帮你 3 步锁定设计方向 【免费下载链接】garden-skills ConardLis open-source Skills collection, featuring web design, knowledge retrieval, image generation, and more. 项目地址: https://gitcode.com/GitHub…

阅读更多 →
护照NAATI翻译怎么办理?一篇读懂渠道、流程及费用 2026/9/16 17:01:27

护照NAATI翻译怎么办理?一篇读懂渠道、流程及费用

一、护照NAATI翻译怎么办理?可以找线上平台,很省事,比如慧办好翻译小程序,对接大型涉外翻译服务机构,也是我国翻译协会会员单位,所有译员持证上岗,无机翻。标价清晰,无隐形收费&…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞