SPM如何指定limit和offset参数格式化?

【概述】 SPM无法为limit和offset指定格式化参数

【TiDB 版本】 V5.2.2

执行SPM绑定

ORDER BY
	xxxx DESC 
	LIMIT '?' OFFSET '?' USING SELECT xxxxx
> 1064 - You have an error in your SQL syntax; check the manual that corresponds to your TiDB version for the right syntax to use line 32 column 11 near "'?' OFFSET '?' USING SELECT
ORDER BY
	xxxx DESC 
	LIMIT '...' OFFSET '...' USING SELECT xxxx
> 1064 - You have an error in your SQL syntax; check the manual that corresponds to your TiDB version for the right syntax to use line 32 column 13 near "'...' OFFSET '...' USING SELECT

limit 和offset该如何通配?
另外还有 limit 0,10这种格式如何适配?

limit x,y

limit x offset y
两种是不同的含义,请参考Mysql 中关键的描述来确定使用的场景

我要解决的是 如何指定通配符。。 不是区分limit x和 limit x,y的含义。。

我意思是 SPM的时候 limit ‘?’ 或者limit '…'都会报语法错误。offset 也是一样的。


这个应该是不指定通配符的,通配符是SPM格式化之后的

所以就是limit 和offset必须写死?

比如 limit 10 或者 offset 100

业务侧千变万化呢

spm比对的时格式化后的sql,不是原始sql否则一个空格换行不一致都不能匹配

SQL 生成执行计划时,同时会生成 SQL指纹 (digest)

SPM 是根据 这个信息来进行绑定的,你也可以通过 digest 来查询

我业务SQL是

select * from t limit 1或 select * from t limit 2

SPM如何写?

假如需要绑定的 hint 是强制使用索引 idx_a,那么可以这样创建绑定:

create binding for select * from t limit 1 using select * from t use index (idx_a) limit 1

创建的绑定会自动把 SQL 中的所有常量替换成 ? 或者 ... 这样的标识符,而不需要人工指定是哪些常量。

这是你的原始sql 想达到什么样的效果,绑定的sql是使用hint等能改变原始sql的执行计划的,sql生成执行计划时会对sql进行格式化然后去比对spm李有没有格式化后的相同sql,然后按照spm里swl计划去执行,原始是limit 1然后绑定后按limit 10的值出来,肯定不行

因为我的原始SQL 有可能 limit 1 ,有可能是limit 2,有可能 limit 10,但是我配置SPM limti ? 报错,我如何在SPM中写limit 通配原始SQL中的任意 limit 常量?

可以参考楼上兄弟回复的演示,就像最后一张图的那样。
创建绑定的时候它会自动识别其中的常量,在 show bindings 的结果中可以看到显示成 ? 或者 ...,就算你实际的 SQL 中的常量是其它的值也是可以匹配上的。

可以了,实际上bingding SQL中limit 后面接任意常量都可以。

这样original SQL就会匹配成 limit …

另外offset会被省略掉。

mysql> select @@last_plan_from_binding;
+--------------------------+
| @@last_plan_from_binding |
+--------------------------+
|                        1 |
+--------------------------+

改变limit的值,只能通过自己的程序进行控制了,不要指望数据库了。

1 个赞

此话题已在最后回复的 1 分钟后被自动关闭。不再允许新回复。