tidb 绑定执行计划,参数化的实现规则

为提高效率,提问时请提供以下信息,问题描述清晰可优先响应。

  • 【TiDB 版本】:tidb v3.0.6和tidb v4.0.2
  • 【问题描述】:部分SQL经常走错索引,想自己开发一个功能实现执行计划变更报警,现发现绑定SQL执行计划可自动把SQL参数化了,SHOW GLOBAL BINDINGS 可看到Original_sql(参数化后用?替换了原来实际参数),想知道用?号替换参数的具体场景或代码或方法,可以吗?

若提问为性能优化、故障排查类问题,请下载脚本运行。终端输出的打印结果,请务必全选并复制粘贴上传。

具体场景指的是什么意思。
走错索引建议从表的健康度和统计信息收集是否即可来看下是否可以通过 tidb 内部的机制来解决此问题。


如图我同一条SQL,不同参数,对应的digest是一样的,也就是说我只要把SQL转换为参数化后就可以判断同一条SQL是否有多个digest,有就判断为有多个执行计划或走错索引,然后自动收集统计信息或人工干预

我这边的情况不定时走错索引,收集统计信息能解决一部份问题,但不及时,我想做成自动的,现在的问题只要解决掉慢查询的query参数化问题就可以解决我的问题了,而参数化问题,在绑定执行计划上是有实现方法的,具体可看SHOW GLOBAL BINDINGS 可看到Original_sql(参数化后用?替换了原来实际参数),只是想知道用?号替换参数的具体场景或代码或方法,如果你们不能提供,我只能用正则自己实现了

比如select id,name from table1 where id=1 和select id,name from table1 where id=2 对应的是同一个digest, 只需要把SQL变成select id,name from table1 where id=?号这样不同的同一条SQL不同参数插入中间表后就变成同一条SQL同一个digest,这样就能区分出哪些SQL走错索引了。而且这转化为参数的方法在tidb绑定变量方法上是实现了的

如果 tidb auto analyze 不能很好的解决 sql 走错索引的问题(可以看下 auto analyze 的策略;根据业务更新频率进行调整)
也可以通过 CREATE BINDINGS 方式来解决,一类 sql 执行计划的问题,可以避免 sql 走错执行计划。如果绑定了还出现了走错,可以反馈给我们。

对于你的方案:
是否可以理解为,在 sql_query 系统表查看 digest 在一类 sql 中是否发生了变化?
风险点为:当集群负载较高,information table slow_query 表查询可能也是慢的,并不能很好的解决你的问题。
写 log 是否异步的,实时性可能没有那么好。
目前当执行 select* from slow_query 时,tidb 会将 slow log 文件中的信息查出来并返回,如果实时监控此系统表,可能对集群带来不必要的负担。

综上,对于 tidb sql 走错索引问题,建议拿出来看下。看通过 sql bind 和 hint 的方式是否可以解决。
https://docs.pingcap.com/zh/tidb/stable/optimizer-hints
https://docs.pingcap.com/zh/tidb/stable/sql-statement-create-binding/#语法说明

这个也许可以通过 information_schema.CLUSTER_STATEMENTS_SUMMARY 表中的 plan_digest 字段来实现

我查了一下这表,没有数据,要怎么才能有数据?

看看 select @@global.tidb_enable_stmt_summary 的值呢,需要设置成 1:

set @@global.tidb_enable_stmt_summary = 1;

是要4.0才有这功能对吧?动态参数吗?不需重启的?

此为 tidb 的系统变量在 v3.0.4 引入
系统变量设置不需要重启 tidb server

https://docs.pingcap.com/zh/tidb/v3.0/tidb-specific-system-variables#tidb_enable_stmt_summary-span-classversion-mark从-v304-版本开始引入span