前言
MySQL在5.7.6开始支持Query Rewrite,能够将符合对应pattern的SQL语句进行重写。如果是普通的只查询单行记录的SQL,如果表小的话,加个索引能够很快的解决问题。但是如果表有几十个G,或者SQL的where条件已经全部都在索引上了,但是执行了count(*)或者group导致扫描了大量数据,除了下线SQL或者停止应用没有别的更好办法,这时候我们可以直接把count(*)的结果拿到,直接RewriteSQL进行返回,这个特性就非常有用了。
我们来实际的测试一下。
Install Plugin
安装创建非常简单,cd 到软件的安装目录的share子目录。
我们可以看到有两个SQL文件,我们来安装
安装上之后,默认就已经启用了Plugin,我们可以通过如下命令进行查看
这时候,就已经创建好了一个query_rewrite库 以及在query_rewrite库里面创建了一张rewrite_rules表。
Plugin 用法
1.添加重新规则
2.将规则刷新到内存里面
当插件读取到rewrite_rules表的记录时,会生成一个normalized_pattern和pattern_digest。normalized_pattern表示常规化的pattern,例如plugin 会把 select count(*) 改写成 select count(?)
3.查看加载失败
如果某个规则加载失败,将显示
从rewrite_rules 表的message列里面可以详细看到失败的原因
4.Rewrite支持的类型
MySQL 5.7的Query Rewrite Plugin 只支持SELECT,在8.0 里面会支持INSERT,UPDATE,DELETE。
The Rewriter query plugin currently only support SELECT statements as patterns. The purpose of this worklog is to expand the Rewriter plugin to support INSERT, UPDATE and DELETE statements. This expansion should be an addition of features and should not break existing functionality in the Rewriter plugin, or the mysql server.
5.查看Rewrite的语句
6.禁用某个rule
7.启用某个rule
8.设置匹配的数据库
在编写rule的时候,要么指定pattern_database字段,要么就直接写到表名里面,例如
否则会出现报错
实操
采用sysbench 表,单表数据量是1000万
python脚本
不用Query Rewrite Plugin的输出
编写Query Rewrite Plugin规则
使用Query Rewrite Plugin的输出
直接改写count(*),让他直接返回,时间上从1.94秒变成了0.07秒,提升非常明显,在业务上无法及时更改count(*) 实现的时候,快速返回count(*)的结果将是一个不错的方法。
压测表现
压测命令:
整体开启rewrite plugin的时候,对数据库整体影响小于1%,在可接受范围内。
小结
在加索引无法解决,加索引时间过长,无法停止业务,修改代码重新发布时间过长等情况下,利用Query Rewrite Plugin来快速改写SQL,消除慢查,恢复数据库,是个不错的选择。
参考资料:
Posted in MySQL