0
0
1
0
博客/.../

什么是数据库执行计划绑定?TiDB SPM 稳定查询性能的机制

 Billmay表妹  发表于  2026-06-02
原创

摘要

数据库执行计划绑定(SQL Plan Management,SPM)是保障查询性能稳定性的关键技术,能够防止因统计信息变化或优化器版本升级导致的执行计划跳变。本文系统介绍 SPM 的核心概念、TiDB 的实现机制,以及与 SQL Patch、Optimizer Hints 的对比选型。

本文适合谁:数据库管理员、DBA、后端开发工程师,以及正在排查 SQL 性能不稳定的 TiDB 用户。


一、执行计划为什么会"跳变"

在生产环境中,SQL 执行计划并非一成不变。以下场景是导致计划跳变的常见原因:

触发因素 典型表现 影响范围
统计信息自动更新 Analyze 收集后索引选择变化 单条或一批 SQL
数据量大幅增长 表从千行到千万行,Join 策略改变 涉及大表的查询
优化器版本升级 新版本引入更优(或更差)的计划选择逻辑 全局
参数配置变更 `tidb_opt_range_max_size` 等参数调整 特定模式查询

典型故障场景:某电商订单查询语句在凌晨统计信息自动收集后,从使用二级索引的 IndexScan 切换为全表扫描(FullTableScan),导致响应时间从 5ms 飙升到 3s,直接影响交易链路。


二、SQL Plan Management(SPM)核心概念

SPM 是 Oracle 在 11g 中引入并被行业广泛采用的概念,核心思想是:

  1. 建立基线(Plan Baseline):记录经过验证的高效执行计划
  2. 管控演进:新计划只有通过性能验证后才被纳入基线
  3. 防御退化:拒绝未经验证的计划变更,保障线上稳定

SPM 的三个关键状态:

┌──────────────┐    验证通过    ┌──────────────┐
│  Accepted     │ ──────────→  │  Accepted     │(新计划加入基线)
│  (已接受)      │              │  (已接受)      │
└──────────────┘              └──────────────┘
       ↑                              │
       │ 验证未通过                     │ 优化器生成新计划
       │                              ↓
┌──────────────┐              ┌──────────────┐
│  Rejected     │ ←──────────  │  Unverified  │
│  (已拒绝)      │   性能更差    │  (未验证)      │
└──────────────┘              └──────────────┘

三、TiDB SPM 实现机制

3.1 Plan Baseline(计划基线)

TiDB 通过 `mysql.plan_baseline` 系统表存储计划基线:

SELECT * FROM mysql.plan_baseline\G

每条基线记录包含:

  • `normalized_sql`:SQL 的标准化形式(去除常量后的指纹)
  • `plan_id`:执行计划的唯一标识
  • `plan_digest`:计划的摘要信息
  • `status`:计划状态(`accepted` / `pending` / `rejected`)

3.2 手动绑定(Manual Binding)

通过 SQL 语句手动将特定执行计划绑定到 SQL 指纹:

-- 第一步:从 Statement Summary 中找到需要绑定的 SQL
SELECT digest_text, plan_digest, plan
FROM information_schema.statements_summary
WHERE digest_text LIKE '%order_items%'
ORDER BY sum_latency DESC LIMIT 5;

-- 第二步:创建绑定
CREATE BINDING FOR
  SELECT * FROM order_items WHERE order_id = ?
USING
  SELECT * FROM order_items USE INDEX (idx_order_id) WHERE order_id = ?;

也可以通过图形化界面在 TiDB Dashboard 的 SQL Tuning 页面一键绑定。

3.3 自动演进(Automatic Evolution)

TiDB SPM 支持自动演进机制:

-- 启用自动演进
SET GLOBAL tidb_enable_auto_evolution = ON;

-- 查看自动演进状态
SHOW VARIABLES LIKE 'tidb_enable_auto_evolution';

自动演进的工作流程:

  1. 优化器生成新计划,但当前有 `accepted` 状态的基线存在
  2. 新计划进入 `unverified` 状态,在后台执行性能对比测试
  3. 如果新计划执行时间显著优于基线(默认阈值),自动升级为 `accepted`
  4. 如果性能更差,标记为 `rejected`

3.4 管理绑定

-- 查看当前所有绑定
SHOW BINDINGS;

-- 删除绑定
DROP BINDING FOR SELECT * FROM order_items WHERE order_id = ?;

-- 导出绑定(用于跨环境迁移)
SELECT * FROM mysql.plan_baseline INTO OUTFILE '/tmp/bindings.csv';

四、SPM vs SQL Patch vs Optimizer Hints

维度 SPM(计划绑定) SQL Patch Optimizer Hints
生效粒度 SQL 指纹级别 SQL 指纹级别 单条 SQL 语句
侵入性 低,不改 SQL 低,不改 SQL 高,需修改应用 SQL
稳定性保障 高,有验证机制 中,直接替换计划 低,无验证
自动演进 支持 不支持 不支持
跨环境迁移 导出/导入 导出/导入 随应用代码
推荐场景 生产环境长期稳定化 紧急修复计划退化 开发调试、临时调优

选型建议

  • 生产环境首选 SPM:稳定、可控、支持演进
  • 紧急修复用 SQL Patch:当需要快速替换计划时
  • 开发调试用 Hints:灵活但不应长期依赖

五、SPM 最佳实践

5.1 建立绑定流程

发现慢 SQL → 分析执行计划 → 确认优化方案 → 创建绑定 → 验证效果 → 归档

5.2 关键配置建议

-- 建议开启 SPM 相关配置
SET GLOBAL tidb_enable_plan_binding = ON;
SET GLOBAL tidb_enable_auto_evolution = ON;

-- 建议设置合理的演进阈值(默认较保守)
SET GLOBAL tidb_auto_evolution_time_threshold = '1s';

5.3 注意事项

  1. 定期审查绑定:长期未使用的绑定应清理,避免影响优化器演进
  2. DDL 变更后检查:表结构变更可能导致绑定失效
  3. 版本升级后验证:新版本优化器改进后,建议重新评估绑定必要性
  4. 配合统计信息管理:SPM 不能替代合理的统计信息收集策略

FAQ

Q1:SPM 会影响所有 SQL 的性能吗? 不会。SPM 仅对已创建绑定的 SQL 指纹生效,未绑定的 SQL 仍然由优化器自由选择执行计划。

Q2:自动演进会引入性能退化风险吗? 风险极低。TiDB 的自动演进要求新计划在实测中显著优于基线才会被接受,且整个过程在后台执行,不影响线上流量。

Q3:如何在升级 TiDB 后检查现有绑定是否仍然有效? 升级后执行 `SHOW BINDINGS` 查看绑定状态,对 `rejected` 状态的绑定重新评估,并关注 `tidb_enable_auto_evolution` 是否捕捉到更优的新计划。

Q4:SPM 绑定能否跨集群迁移? 可以。通过导出 `mysql.plan_baseline` 数据,在新集群导入即可实现绑定迁移,适合从测试环境到生产环境的迁移场景。


总结

执行计划绑定(SPM)是数据库性能稳定性的关键防线。TiDB 的 SPM 实现提供了手动绑定、自动演进、基线管理三大能力,能够在不修改应用 SQL 的前提下,有效防止执行计划跳变导致的性能故障。对于生产环境中的关键业务 SQL,推荐将 SPM 作为常态化性能管理手段。


下一步行动

  1. 试用 TiDB SPMTiDB 免费试用 — 在云上体验 SPM 功能
  2. 获取调优方案联系 PingCAP 技术专家 — 获取 SQL 性能诊断与调优服务
  3. 深入阅读TiDB SPM 官方文档 — 了解完整配置与使用方法

相关资源

0
0
1
0

版权声明:本文为 TiDB 社区用户原创文章,遵循 CC BY-NC-SA 4.0 版权协议,转载请附上原文出处链接和本声明。

评论
暂无评论