SQL 运行数据收集:数据清洗最终方案¶
分支文档快照 · 同步于 2026-09-09 · 来源:
origin/summer-intern@9f4cdc5· 原路径:docs/data/01-SQL数据清洗方案.md。正文描述的是该分支的方案或进展,合入与验收状态以当前看板为准。
1. 目标与适用范围¶
本方案用于固定测试环境、单批次 50 条以内 SQL 的轻量化治理。目标是让每条 SQL 在进入基线测试前满足:
- 可唯一识别:同一条 SQL 有稳定的
case_id和sql_fingerprint。 - 可重复执行:执行所需数据库、参数集和环境信息齐全。
- 可比较:原 SQL 与优化 SQL 使用相同参数集和数据快照。
- 可追踪:原始 SQL 永久保留,清洗状态和人工调整均有记录。
- 可执行:第一阶段使用一个 Excel 文件即可管理,不依赖额外平台。
建议 Excel 使用以下 Sheet:
01_SQL台账02_参数集
原始记录遵循“只追加、不覆盖”原则。sql_raw、历史参数集以及已使用的指纹不可直接修改;如需调整,创建新版本并保留旧记录。
2. 标准流程¶
原始SQL导入
↓
完整性检查
↓
SQL格式标准化
↓
参数抽取与参数集建立
↓
SQL指纹计算与去重
↓
EXPLAIN/语法预检
↓
ready / review / excluded
2.1 完整性检查¶
以下字段必须存在:
- 来源系统或业务条线
- 数据库名称
- 原始 SQL
- 可用于执行的参数或参数来源
缺少数据库、SQL 或参数集时,clean_status 标记为 review,不得进入基线测试。
2.2 SQL 标准化¶
sql_clean 仅进行不改变语义的处理:
- 统一换行、缩进、多余空格和尾部分号。
- 去除不影响语义的普通注释。
- 保留 Hint、表名、字段名、函数和业务逻辑。
- 将运行时变化的常量替换为命名占位符,形成参数化模板。
示例:
原始 SQL:
SELECT * FROM orders
WHERE user_id = 10086
AND status = 'PAID'
AND create_time >= '2026-06-01';
清洗后的模板:
SELECT *
FROM orders
WHERE user_id = :user_id
AND status = :status
AND create_time >= :start_time;
2.3 参数抽取与参数集建立¶
参数来源优先级:
- 生产慢 SQL 日志或审计记录中的真实绑定值。
- SQL 审核平台中已经携带的常量。
- 应用日志或 APM 中的调用参数。
- 从测试数据库只读抽样得到的典型值。
- 人工构造值,仅作为兜底,并标记来源为
manual。
建议抽取:
- 数字、字符串、日期和时间常量。
IN (...)的值列表。LIMIT数量和模糊查询关键词。- 分片键、租户 ID 等影响路由或数据量的值。
通常不抽取:
- 表名、字段名和函数名。
- Hint。
- 明确硬编码且属于固定业务逻辑的状态值。
第一阶段每条 SQL 至少建立一个 typical 参数集;只有数据倾斜或边界风险明显时,再增加:
heavy:大客户、长时间范围、大结果集等高负载场景。boundary:空结果、空值、超长IN列表等边界场景。
每条 SQL 最多维护三个有效参数集,避免组合爆炸。
2.4 指纹与去重¶
sql_fingerprint 基于参数化、格式规范化后的 SQL 模板生成,建议使用 SHA-256。相同指纹说明 SQL 结构相同,但不能直接证明业务语义完全相同。
去重规则:
- 同一批次、同一数据库、同一指纹:保留一个主 Case。
- 重复记录通过
duplicate_of_case_id指向主 Case。 - 不同数据库中的相同 SQL 不合并,因为执行计划和表数据可能不同。
- 指纹相同但业务归属或权限上下文不同的记录,由人工确认是否合并。
2.5 可执行性预检¶
对清洗后的 SQL 执行语法检查或 EXPLAIN:
ready:信息齐全、参数有效、可安全执行。review:缺参数、缺对象、权限不足或需人工判断。excluded:高风险写操作、无法安全执行或不属于优化范围。
第一阶段默认只允许只读查询进入自动基线。DML/DDL 必须进入隔离环境并经过人工批准。
3. 表一:01_SQL台账¶
3.1 字段定义¶
| 字段 | 必填 | 示例 | 说明 |
|---|---|---|---|
| batch_id | 是 | 20260717_B01 | 本次收集批次 |
| case_id | 是 | CAMS_0001 | SQL 唯一编号 |
| db_name | 是 | tdsql_camsdb | 目标数据库 |
| db_mode | 是 | centralized | centralized/distributed |
| sql_raw | 是 | SELECT ... | 永久保留的原始 SQL |
| sql_clean | 是 | SELECT ... :user_id | 清洗后的参数化模板 |
| sql_fingerprint | 是 | sha256:a91f... | 参数化 SQL 指纹 |
| primary_parameter_set_id | 是 | P_CAMS_0001_01 | 默认典型参数集 |
| clean_status | 是 | ready | ready/prepare/excluded |
| exclude_reason | 否 | 空 | 排除或阻塞原因 |
| duplicate_of_case_id | 否 | 空 | 重复 SQL 对应的主 Case |
| created_at | 是 | 2026-07-17 09:30:00 | 首次收录时间 |
| updated_at | 是 | 2026-07-17 10:05:00 | 最近更新时间 |
| updated_by | 是 | lisi | 最近修改人 |
3.2 具体示例¶
| batch_id | case_id | source_system | db_name | db_mode | sql_raw | sql_clean | sql_fingerprint | primary_parameter_set_id | clean_status | exclude_reason | duplicate_of_case_id | owner | created_at | updated_at | updated_by |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 20260717_B01 | CAMS_0001 | CAMS | tdsql_camsdb | centralized | SELECT * FROM orders WHERE user_id=10086 AND status='PAID' AND create_time>='2026-06-01'; |
SELECT * FROM orders WHERE user_id=:user_id AND status=:status AND create_time>=:start_time; |
sha256:a91f72c8 | P_CAMS_0001_01 | ready | zhangsan | 2026-07-17 09:30:00 | 2026-07-17 10:05:00 | lisi | ||
| 20260717_B01 | CAMS_0002 | CAMS | tdsql_camsdb | centralized | SELECT * FROM orders WHERE user_id=20001 AND status='PAID' AND create_time>='2026-07-01'; |
SELECT * FROM orders WHERE user_id=:user_id AND status=:status AND create_time>=:start_time; |
sha256:a91f72c8 | P_CAMS_0002_01 | excluded | 与 CAMS_0001 同库同指纹,合并追踪 | CAMS_0001 | wangwu | 2026-07-17 09:35:00 | 2026-07-17 10:08:00 | lisi |
第二行没有被删除,而是保留来源并关联主 Case,以便统计原始问题数量和去重后有效 SQL 数。
4. 表二:02_参数集¶
4.1 字段定义¶
| 字段 | 必填 | 示例 | 说明 |
|---|---|---|---|
| parameter_set_id | 是 | P_CAMS_0001_01 | 参数集唯一编号 |
| case_id | 是 | CAMS_0001 | 关联 SQL |
| set_type | 是 | typical | typical/heavy/boundary |
| parameter_values | 是 | JSON 文本 | 参数名到参数值的映射 |
| parameter_source | 是 | slow_log | slow_log/audit/apm/db_sample/manual |
| source_reference | 否 | trace-98301 | 原始日志或审计记录引用 |
| data_snapshot | 是 | SNAP_20260717 | 使用的数据快照 |
| sensitivity_level | 是 | internal | public/internal/sensitive |
| valid_status | 是 | valid | valid/review/expired |
| created_at | 是 | 2026-07-17 09:50:00 | 创建时间 |
| note | 否 | 普通用户近30天订单 | 参数代表性说明 |
4.2 具体示例¶
| parameter_set_id | case_id | set_type | parameter_values | parameter_source | source_reference | data_snapshot | sensitivity_level | valid_status | created_at | created_by | note |
|---|---|---|---|---|---|---|---|---|---|---|---|
| P_CAMS_0001_01 | CAMS_0001 | typical | {"user_id":10086,"status":"PAID","start_time":"2026-06-01"} |
slow_log | trace-98301 | SNAP_20260717 | internal | valid | 2026-07-17 09:50:00 | zhangsan | 普通用户近30天订单 |
| P_CAMS_0001_02 | CAMS_0001 | heavy | {"user_id":90001,"status":"PAID","start_time":"2025-07-01"} |
db_sample | sample-job-0717 | SNAP_20260717 | internal | valid | 2026-07-17 09:55:00 | zhangsan | 大客户近一年订单 |
敏感参数不应直接写入共享 Excel。可保存脱敏值或安全存储中的引用,并将 parameter_values 写为 {"user_id_ref":"vault://params/98301"}。
5. 数据质量规则¶
阶段一:
进入基线测试前必须同时满足:
case_id、db_name、sql_raw不为空。
阶段二:
case_id、db_name、sql_raw、sql_clean不为空。clean_status = ready。primary_parameter_set_id在02_参数集中存在且valid_status = valid。- 参数集的
case_id与 SQL 台账一致。 - 参数集对应的数据快照可用。
- 同一
case_id只对应一个原始 SQL 指纹。
6. 清洗阶段看板¶
第一阶段只追踪:
| 指标 | 计算方式 |
|---|---|
| 原始 SQL 数 | 01_SQL台账 总行数 |
| 去重后有效 SQL 数 | clean_status=prepare 且非重复记录数 |
| 可执行率 | prepare 数 ÷ 原始 SQL 数 |
| 待处理数 | clean_status!=prepare 数 |
| 排除数 | clean_status=excluded 数 |
7. 最小执行清单¶
每个批次由执行人依次完成:
- 导入原始 SQL,生成
batch_id和case_id。 - 保留
sql_raw,生成sql_clean和sql_fingerprint。 - 为每条有效 SQL 建立至少一个
typical参数集。 - 完成同库指纹去重并保留重复来源。
- 执行语法检查或
EXPLAIN。 - 将 SQL 标记为
ready/review/excluded。 - 复核质量规则,通过后交给基线流程。