- 人工智能
- 深度学习
- NLP
- 计算机视觉
- 强化学习
【免费下载链接】google-research
Google Research
导读
本指南系统讲解 CardBench(关系数据库学习型基数估计基准)的核心数据资产——训练查询图(Training Query Graphs)。你将理解三个训练数据集(单表、二表连接、多表连接)的构成与规模、查询图的节点/边特征模式(Schema)、以及如何使用 sparse-deferred 库读取.npz格式的训练数据并提取基数、执行时间、SQL 等标注信息,为训练或评估基数估计模型(包括零样本场景)打下数据基础。文中所有示例均可直接运行,并有仓库源码佐证其底层实现。
什么是 CardBench 训练查询图
CardBench 是 Google Research 发布的用于关系数据库学习型基数估计(Learned Cardinality Estimation)的基准,仓库中同时包含两部分内容:训练数据集(位于training_datasets目录)与生成训练数据集的完整代码。其中,训练查询图正是 TrainingQueryGraphs.md 所详细描述的核心交付物。
每个训练实例都是一条 SQL 查询的"带注释图"(annotated graph):原始 SQL 字符串被翻译为关系代数算子、查询计划,最终转换为图结构;同时,通过真实数据库(Google BigQuery)执行该查询得到的**实际基数(cardinality)**被作为上下文信息写入图中。因此,每条训练样本同时包含:
- 查询本身的执行语义(以节点和边编码);
- 查询涉及的数据库对象统计信息(表行数、列分位数、空值比例等);
- 查询的真实执行结果(cardinality)与执行时间(exec_time)等顶层标签。
CardBench 的训练数据集按查询复杂度分为三档,三者的差异在于查询包含的操作类型:
| 数据集 | 查询形态 | 谓词规模 |
|---|---|---|
| Single Table(单表) | 对单张表应用过滤 | 每查询 1–4 个过滤谓词 |
| Binary Join(二表连接) | 连接两张表 | 每张表 1–3 个过滤谓词 |
| Multi Join(多表连接) | 1–7 个连接 | 每张表 0–2 个过滤谓词 |
下面分别是官方文档给出的单表与二表连接查询示例:
-- Single Table 示例 SELECT count(*) FROM tpch_10G.nation as nation WHERE nation.n_nationkey <= 6 AND nation.n_comment IS NULL AND nation.n_regionkey >= 1;-- Binary Join 示例 SELECT count(*) FROM tpch_10G.region as region JOIN tpch_10G.nation as nation ON region.r_regionkey = nation.n_regionkey WHERE nation.n_comment IS NOT NULL AND nation.n_nationkey != 5;这些查询的真实基数是在 Google BigQuery 上执行后获得并作为图上下文(context)写入的,SQL 字符串本身也包含在图上下文之中。
训练数据的下载与文件命名规范
训练数据集以.npz文件形式提供,命名规范为:
database_name_<single_table|binary_join|multi_join>.npz例如consumer_single_table.npz、tpch_10G_binary_join.npz、accidents_multi_join.npz。下载方法与全部制品链接(数据集 CSV、建表 SQL、复制脚本、元数据 JSON、查询图文件)请参考 DowloadArtifacts.md。文档特别说明:数据库名称中的~标记表示该数据库已被降采样(down sampled)。
训练数据集总览
下表列出了 20 个数据库的规模信息:每个数据库包含的表数量、以及各数据集(单表/二表连接/多表连接)的查询图数量。这些查询图由不同复杂度的查询生成,是训练与评估(含零样本)基数估计模型的基础:
| 数据集名称 | 表数 | 单表查询数 | 二表连接查询数 | 多表连接查询数 |
|---|---|---|---|---|
| accidents | 3 | 9125 | 8454 | 29242 |
| airline | 19 | 6568 | 13096 | 10467 |
| consumer | 3 | 5961 | 5571 | 11857 |
| employee | 6 | 12675 | 10417 | 11041 |
| movielens | 13 | 14488 | 15757 | 17067 |
| sample_cms_synthetic_patient_data_omop | 24 | 9574 | 6536 | 10038 |
| sample_covid19_weathersource_com | 4 | 9366 | 10186 | 16075 |
| sample_crypto_bitcoin_cash | 2 | 14315 | 12404 | 17114 |
| sample_ethereum_blockchain | 7 | 19756 | 17424 | 19962 |
| sample_geo_openstreetmap | 16 | 16346 | 15000 | 10979 |
| sample_github_repos | 9 | 5268 | 4513 | 10564 |
| sample_human_variant_annotation | 26 | 13862 | 14085 | 12162 |
| sample_idc_v10 | 19 | 8609 | 6464 | 12081 |
| sample_open_targets_genetics | 13 | 9734 | 9058 | 10025 |
| sample_samples | 8 | 8893 | 11369 | 10832 |
| sample_stackoverflow | 14 | 14305 | 12773 | 11399 |
| sample_usfs_fia | 11 | 13822 | 11787 | 10980 |
| sample_uspto_oce_claims | 12 | 5925 | 6123 | 11968 |
| sample_wikipedia | 25 | 6659 | 7375 | 10739 |
| tpch_10G | 8 | 11727 | 13181 | 16318 |
观察可见,多数数据库的查询图总量在数万级别;accidents的多表连接查询数高达 29242,是全表中最多的。用户可按需组合这些文件构建自己的训练/验证/测试划分,例如在零样本实验中用其中 19 个数据库训练、留出 1 个数据库做测试(仓库中 graph_transformer/README.md 提供了这种划分的完整命令)。
查询图结构:节点类型、特征与边的 Schema
CardBench 查询图是一种异构图(heterogeneous graph)。下图为查询图的结构示意:左侧列出了各节点类型及其特征与数据类型,右侧则可视化了一个具体示例查询对应的图:
图中的核心观察:
- 节点类型包括
tables(表)、attributes(列/属性)、predicates(谓词)、ops(算子,如 scan/join)、correlations(列间相关关系),外加一个表示全局上下文的特殊节点g(在官方示例输出中以'g'出现)。 - 边类型则刻画了这些节点之间的语义关系,如
table_to_attr(表到列)、attr_to_pred(列到谓词)、pred_to_pred(谓词组合,如 AND/OR)、attr_to_op(列到算子)、op_to_op(算子之间)、pred_to_op(谓词到算子)、attr_to_corr/corr_to_pred(列到相关关系、相关关系到谓词)。
从仓库源码 constants.py 可以确认图结构的完整定义:NODE_TYPES包含pseudo_node、attributes、ops、predicates、correlations、tables六类,EDGE_TYPES则定义了 9 种边(含pseudo_edge)。各节点的具体特征如下:
| 节点类型 | 特征(features) | 说明 |
|---|---|---|
g(全局上下文) | cardinality、exec_time、query_id、query(SQL 字符串)等 | 一条查询的顶层信息与监督标签 |
tables | rows(行数)、name(表名) | 表级统计 |
attributes | name、data_type、null_frac(空值比例)、num_unique(唯一值数)、percentiles_100_numeric/percentiles_100_string(101 位分位数)、min/max_numeric、min/max_string | 列级统计 |
predicates | predicate_operator(算子编码)、estimated_selectivity(估计选择率)、offset(长度 6 的偏移向量)、constant、encoded_constant | 谓词信息 |
ops | operator(如scan、join) | 执行算子 |
correlations | type、correlation(Pearson 相关系数)、validity | 列间相关性 |
特征填充规则与占位值
文档在 Notes 中明确了两条重要规则:
- 按属性类型选择性填充特征:
percentiles_str(字符串分位数)只对STRING类型属性填充,percentiles_num(数值分位数)只对数值类型属性填充。这点在源码 convert_query_plan_to_graph.py 中得到了印证:只有INT64、NUMERIC、BIGNUMERIC、FLOAT64、DECIMAL、BIGDECIMAL类型才会写入min_numeric/max_numeric,否则填-1;percentiles_100若缺失则填充 101 个-1.0。 - 空特征统一填充
-1:任何未填充的特征占位值均为-1。
从 constants.py 还可以看到,训练图 Transformer 在预处理时会移除部分非数值特征(如attributes.name、min/max_string、percentiles_100_string、predicates.constant等),并把data_type、operator、predicate_operator、validity等作为分类特征做 one-hot 化(CATEGORICAL_FEATURE_UNIQUE_DICT),最终拼成维度为NODE_FEATURE_DIM = 150的节点特征向量,用于 graph_transformer 模型输入。
此外,各数据库更完整的统计信息可在 DowloadArtifacts.md 中获取,查询图中已经内嵌了一部分数据集统计信息。
如何读取训练数据(sparse-deferred 实战)
训练数据使用 Sparse Deferred 正是查询图生成管线中负责把图转换为 sparse-deferredGraphStruct对象并最终写入.npz文件的模块。
环境要求
运行下述读取代码需要:
- Python >= 3.10
sparse-deferrednumpy
三者均可通过 pip 安装。
加载训练数据集
训练数据集以分片(sharded)方式存储(即拆分为多个文件),可用 glob 找到某个数据集的所有分片。以下代码加载consumer_single_table数据集并打印训练实例数量:
from sparse_deferred.structs import graph_struct GraphStruct = graph_struct.GraphStruct InMemoryDB = graph_struct.InMemoryDB # 训练数据集按分片存储,使用 glob 查找某数据集的所有分片 filename = "single_table/consumer_single_table.npz" db = InMemoryDB.from_file(filename) # 打印训练实例数量 print("Number of training instances:", db.size)输出:
Number of training instances: 5571该数字与上表consumer单表查询数 5961 存在差异,原因在于查询图生成过程中会过滤掉重复查询与零基数查询(见下文"源码佐证")。
查看 Schema 与节点类型
# 打印训练实例的 schema print("Schema:", db.schema)输出:
Schema: {'table_to_attr': ('tables', 'attributes'), 'attr_to_pred': ('attributes', 'predicates'), 'pred_to_pred': ('predicates', 'predicates'), 'attr_to_op': ('attributes', 'ops'), 'op_to_op': ('ops', 'ops'), 'pred_to_op': ('predicates', 'ops'), 'attr_to_corr': ('attributes', 'correlations'), 'corr_to_pred': ('correlations', 'predicates')}# 打印节点类型 print("Node types:", first_training_example.nodes.keys()) # 打印表节点的特征 print("Table node features:", db.get_item(0).nodes["tables"].keys())输出:
Node types: dict_keys(['g', 'tables', 'attributes', 'predicates', 'ops', 'correlations']) Table node features: dict_keys(['rows', 'name'])# 打印边类型 print("Edge types:", first_training_example.edges.keys())访问表节点信息
# 打印第一个表节点的行数和表名 print( "First table number of rows:", db.get_item(0).nodes["tables"]["rows"][0] ) print("First table name:", db.get_item(0).nodes["tables"]["name"][0])输出:
First table number of rows: 340872 First table name: b'bq-cost-models-exp.consumer.HOUSEHOLDS'访问图级特征(基数、执行时间、SQL)
cardinality、exec_time、query_id、query等是图级(graph level)特征,即查询本身的监督标签:
# 打印查询基数、执行时间、query_id 与 SQL 字符串(均为图级特征) print( "Query cardinality:", first_training_example.nodes["g"]["cardinality"][0], ) print("Execution time:", first_training_example.nodes["g"]["exec_time"][0]) print("Query id:", first_training_example.nodes["g"]["query_id"][0]) print("Query:", first_training_example.nodes["g"]["query"][0])输出:
Query cardinality: 824130 Execution time: 2390.0 Query id: 14211 Query: b'SELECT count(*) as rwcnt FROM `bq-cost-models-exp.consumer.HOUSEHOLDS` as HOUSEHOLDS JOIN `bq-cost-models-exp.consumer.HOUSEHOLD_MEMBERS` as HOUSEHOLD_MEMBERS ON HOUSEHOLDS.HOUSEHOLD_ID = HOUSEHOLD_MEMBERS.HOUSEHOLD_ID;\n'打印完整训练实例
# 获取并打印第一个训练实例 first_training_example = db.get_item(0) print("First training example:", first_training_example)输出为完整的GraphStruct序列化表示,包含全部节点特征(如attributes节点的null_frac、num_unique、percentiles_100_numeric、percentiles_100_string等)与 8 类边的邻接索引。例如上面这个 consumer 二表连接查询实例中:
ops节点为[b'join', b'scan', b'scan'](一个 join 算子加两个 scan 算子);predicates节点为空(该查询没有过滤谓词,仅做连接);correlations节点为空数组(未计算相关关系)。
一个值得注意的细节:该示例查询实际上是一条二表连接(HOUSEHOLDS JOIN HOUSEHOLD_MEMBERS),但它出现在单表数据集的加载演示中——官方文档选取此例是为了演示InMemoryDB的读取 API,读者在实际使用时应按数据集类型(single_table/binary_join/multi_join)选择对应文件。
源码佐证:查询图是如何生成的
了解查询图"从哪来",有助于正确解读图内容。根据 README.md 与generate_training_querygraphs_library目录,查询图的生成是 CardBench 代码管线的最后一步:
- 生成 SQL 查询(generate_queries_and_save_to_file.py,基于 DataManagementLab 的 zero-shot-cost-estimation 查询生成器改进);
- 执行查询收集真实基数(run_queries.py,将每条查询的 SQL 与 cardinality 存入
QUERY_RUN_INFORMATION_TABLE); - 生成带注释查询图(generate_training_querygraphs_and_save_to_file.py):SQL 字符串 → 关系代数算子(convert_sql_to_relational_operators.py)→ 查询计划(convert_relational_operators_to_query_plan.py)→ 图(convert_query_plan_to_graph.py),并注释数据集统计信息;
- 保存为 sparse-deferred 格式(create_sparse_deferred_graph_struct_object.py,
InMemoryDB收集图对象后统一写入.npz文件)。
其中两条源码事实值得注意:
- 去重与零基数过滤:在 generate_training_querygraphs_helpers.py 的
find_unique_and_non_zero_cardinality_queries中,生成时会剔除cardinality == 0的查询,并基于"表集合 + 谓词(含常量/不含常量)"构造签名字符串来去除重复查询计划。这就是为什么最终.npz中的实例数通常少于原始生成的查询数。 - 查询图校验:在 validate_query_plan_and_graph.py 中,生成后会做严格校验:每张图必须满足"join 节点数 = SQL 中 JOIN 数、scan 节点数 = 表数"等约束;每个 column 节点必须携带
min_val、max_val、percentiles、percentiles_100(长度必须为 101)、null_frac、num_unique等字段;相关关系节点的correlation值与validity状态(如valid、nan、missing、invalidtypes、none)必须相互匹配。
这些校验规则解释了读取数据时看到的各种占位值(如-1填充、-10/-20/-50等特殊相关系数取值),帮助读者判断某个特征"缺失"是语义上的正常占位还是异常。
下一步:将查询图用于基数估计模型
读取查询图后,最直接的用法是训练或评估基数估计模型。仓库提供了配套的图 Transformer 实现,位于 graph_transformer 目录,其工作流程为:
- 构建缩放策略:用 build_scaling_strategy.py 在所有训练数据集上计算全局统计(数值特征缩放参数),输出
scaling_strategy.json; - 预处理:用 preprocess_dataset.py 将
.npz查询图批量转换为 TF Dataset; - 训练:用 train.py 支持三种模式:
- 实例内模型(instance based):同一数据集训练并测试;
- 零样本模型(zeroshot):在 19 个数据集上训练,在留出的第 20 个数据集上测试(对应论文中的零样本基数估计评估);
- 微调模型(finetuned):加载预训练 checkpoint 后在目标数据集上微调。
模型以cardinality(或exec_time)为标签进行训练(见 constants.py 的LABELS),输入即本指南所介绍的查询图。
小结
- CardBench 提供三个层次复杂度的训练查询图(单表/二表连接/多表连接),共覆盖 20 个数据库、每库数千至数万条查询实例;
- 每个实例是以 SQL 查询为中心构建的异构图:节点类型含
g、tables、attributes、predicates、ops、correlations,边类型含 8 类语义关系,并内嵌真实基数、执行时间与 SQL 字符串作为图级上下文; - 特征按属性类型选择性填充(字符串列用
percentiles_100_string,数值列用percentiles_100_numeric),缺失统一用-1占位; - 读取数据仅需
sparse-deferred+numpy,通过InMemoryDB.from_file(...)即可加载并访问节点特征与图级标签; - 数据集的生成代码、校验逻辑与配套的图 Transformer 模型均已在仓库中开源,可复现数据管线或直接训练模型。
- 人工智能
- 深度学习
- NLP
- 计算机视觉
- 强化学习
【免费下载链接】google-research
Google Research
相关推荐
5大核心技术深度解析:Docker CLI远程连接架构与安全实践
5大核心技术深度解析:Docker CLI远程连接架构与安全实践 Docker CLI远程连接配置是现代容器化运维的核心技术,它允许开发者从本地环境安全地管理和
CLI开发工具Vanna AI训练数据终极指南:从零到一构建智能数据库查询系统
Vanna AI训练数据终极指南:从零到一构建智能数据库查询系统 想要让AI准确理解你的数据库并生成精准SQL查询?Vanna AI通过创新的RAG技术解决了这
人工智能AI AgentRAG数据库后端数据可视化DeepSpeech 训练脚本命令行 Flags 完全指南:从训练、评估到导出的参数速查手册
DeepSpeech 训练脚本命令行 Flags 完全指南:从训练、评估到导出的参数速查手册 导读 本文是 DeepSpeech 项目训练脚本家族的命令行参数(
人工智能语音音频深度学习
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考