查询没改、代码没动,却突然变慢?TiDB SQL Plan Binding 让 DBA 不改应用就能锁计划

> 生产环境里最阴险的性能问题之一:查询跑了几个月都稳,某天突然开始爬。代码没改、SQL 没动,变的是优化器选的执行计划。TiDB 内置的 SQL Plan Management(SPM)给了 DBA 一个不用动应用的解法。原文来自 Mydbops(作者 Kabilesh,两次获 TiDB Community Champion)。

执行计划回归:问题从哪来

TiDB 的代价优化器会为每条查询生成并评估多条执行路径,用统计信息、数据分布、谓词选择率、基数估计、ORDER BY/LIMIT 算成本挑最便宜的。多数时候很可靠——但当统计信息过期、数据分布漂移、复杂查询基数估不准时,优化器就会挑一条明显更贵的路。

SQL Plan Binding 的作用:把优化器 hint 透明地附加到进入的 SQL 上。应用继续发它原本”干净”的无 hint 查询,TiDB 在背后匹配查询、附加绑定的 hint、产出你要的计划。事故现场不用等代码评审、QA、发布和回滚计划。

标准操作流程

第 1 步:先测 hint,别直接绑。 用 EXPLAIN ANALYZE 直接跑带 hint 的语句,紧接着 SHOW WARNINGS——hint 拼错、索引不存在、与查询结构冲突都会在这里暴露。优化器应用不了的 hint,绑了也白绑。

第 2 步:在明确的库上下文里创建全局绑定。 先 USE ; 再建绑定,绑定记录会把表名限定到对应库(如 employee.users)。

匹配靠 SQL 规范化,不是逐字符比对:TiDB 会剥掉字面量常量、解析对象命名空间、去多余空白,形成 SQL digest——所以一个绑定覆盖同一查询的所有参数变体。

验证绑定存在:SHOW GLOBAL BINDINGS;,重点看 Status(enabled)和 Default_db 是否对上执行库。

确认查询真的用上了:

  • 跑完应用查询立刻 SELECT @@LAST_PLAN_FROM_BINDING; ——返回 1 才是真用上了
  • 或跑 verbose explain,命中时 TiDB 会输出提示具体 bind_sql 的 information note
  • 绑定可以覆盖应用内嵌 hint:管理员绑定的优先级高于代码里的 hint。应急时是好事,但也意味着开发者看代码看不出计划为何如此——变更记录必须跟上。

    删除绑定:schema 变更、加索引、版本升级后绑定多余了就 drop,TiDB 将全局绑定记录标记删除并传播到所有节点。

    最容易误解的点:GLOBAL 不是”全库同名表”

    GLOBAL 不意味着这个绑定匹配所有库里叫 users 的表。它定义的是绑定的生命周期和作用域跨节点(集群级 vs 会话级),配合创建时记录的默认库上下文来限定表。

    今天的好计划,明天可能变坏计划

    这是全文最重要的一条运维规则,作者给了一个真实场景:

  • 第 1 个月:强制走索引 A 很快,因为过滤条件只匹配 0.5% 的行
  • 第 6 个月:数据分布变了,70% 的行都匹配——索引逐行回表远不如直接全表扫
  • 无限期锁死的计划,会变成你当初想解决的那个瓶颈。 每个绑定都要当”有生命周期的运维对象”管:发现回归 → 找回已知好计划 → 测 hint → 建绑定 → 验证生效 → 盯延迟/RU/扫描行数 → 定期复审 → 不需要了就解绑。

    进阶玩法:TiDB 的 Statement Summary 表存了历史执行,可以直接拿早上跑得快时的 plan digest 反向绑定,TiDB 自动重建所需 hint(复杂多表 join 仍要 EXPLAIN 复核)。

    事故收尾 Checklist

  • 新旧计划各跑 EXPLAIN ANALYZE,对比耗时、扫描行数、扫描键数、内存、RU
  • hint 单独跑通、SHOW WARNINGS 干净
  • 建绑定前 USE
  • SHOW GLOBAL BINDINGS 里 Status 为 enabled
  • 无 hint 跑一遍,SELECT @@LAST_PLAN_FROM_BINDING 返回 1
  • 写进 DBA 变更记录:为什么加、谁加的、何时复审
  • 盯住集群资源和 RU 曲线,确认是计划问题还是容量问题
  • TiDB SQL Plan Binding 工作流

    小夏点评

  • 这套流程本质是把”改代码才能加的 hint”变成 DBA 侧的运行时配置——事故窗口里分钟级恢复,值得写进 MySQL 系 DBA 的应急手册。
  • @@LAST_PLAN_FROM_BINDING 这个验证开关很多 DBA 不知道:绑定存在 ≠ 绑定生效,上线后必须实测一次。
  • 对国内 IT 运维/开发者的启示:数据分布会漂移,绑定要设复审日期,别让它变成半年后的隐性炸弹;TiDB 这套 SPM 思路(规范化匹配 + digest 绑定)对任何带优化器的系统都是可借鉴的治理模型。
  • 参考链接

  • 原文:https://www.mydbops.com/blog/tidb-sql-plan-binding-performance-tuning
  • 发表回复

    您的邮箱地址不会被公开。 必填项已用 * 标注