MySQL查询重写插件的使用

查询重写插件

从MySQL 5.7.6开始,MySQL Server支持查询重写插件,可以在服务器执行之前检查并可能修改服务器接收的语句。

以下是官方文档介绍:

预解析重写插件具有以下特点:

1.该插件允许在服务器处理之前重写到达服务器的SQL语句。

2.该插件接收一个语句字符串,并可能返回一个不同的字符串。

后解析查询重写插件具有以下特征:

1.该插件支持基于解析树的语句重写。

2.服务器解析每个语句并将其解析树传递给插件,插件可以遍历树。插件可以将原始树返回到服务器以进行进一步处理,或者构造不同的树并返回该树。

通俗来讲,是指该插件支持两种重写方式,一种是在语法解析之前,直接修改SQL字符串,一种是在语法解析之后,通过操控语法解析树来进行重写。这个特性还是非常有用的,例如错误的上线了某个SQL,但由于无法走到索引导致全库查询; 或者你可能使用某个第三方的已编译好的软件,但SQL可能执行错误,你又无法直接修改应用,这个特性将会非常有用,还可以去编写符合用户要求的插件。

安装或卸载

最简单的安装过程如下:

shell> mysql -u root -p < install_rewriter.sql Enter password: (enter root password here)

可以发现,在数据库中多增加了一个库query_rewrite,查看该数据库:

查看插件当前是否安装:

实践操作

例如为如下语句强制使用主键查询:

SELECT DBA_no, name from DBA_inf where DBA_no = ?

改写成:

SELECT DBA_no, name from DBA_inf force index(primary) where DBA_no = ?

要为Rewriter插件添加规则,具体步骤分为两步:

1.向rewrite_rules表中添加相应的规则;

2.调用flush_rewrite_rules()存储过程以将表中的规则加载到插件中。

以下示例创建一个简单规则来匹配选择单个文字值的语句,执行的操作:

insert into query_rewrite.rewrite_rules(pattern, replacement, pattern_database) values ("SELECT DBA_no, name from DBA_inf where DBA_no = ?","SELECT DBA_no, name from DBA_inf force index(primary) where DBA_no = ?","DBAs");

查询刚刚插入的规则:

输出的规则每一列的内容如下:

id:

规则ID。此列是表主键。可以使用该ID唯一标识任何规则。

pattern:

指示规则匹配的语句模式的模板,使用?表示匹配的数据值。

pattern_database:

该数据库用于匹配语句中的非限定表名。如果相应的数据库和表名相同,则语句中的限定表名与模式中的限定名匹配;当默认数据库pattern_database与表名相同且语句名相同时,语句中的非限定表名才匹配模式中的非限定名称 。

replacement:

指示如何重写与pattern列值匹配的语句的模板。使用 ?表示匹配的数据值,?是参数标记,实际语句中可以替换。

enabled:

规则是否已启用。加载操作(通过调用flush_rewrite_rules() 存储过程执行)Rewriter仅在此列加载时才将表中的规则加载到 内存缓存中YES。此列可以在不删除规则的情况下停用规则:将列设置为除YES表之外的值 ,然后将表重新加载到插件中。

message:

该插件使用此列与用户进行通信。如果将规则表加载到内存中时没有发生错误,则插件会将message 列设置为NULL。非NULL值表示错误,列内容是错误消息。在这些情况下可能会发生错误:1.模式或替换是一个产生语法错误的错误SQL语句。2.替换包含比模式更多的参数标记。如果发生加载错误,插件还会将 Rewriter_reload_error状态变量设置为ON。

pattern_digest:

此列用于调试和诊断。如果在将规则表加载到内存中时该列存在,则插件会使用模式摘要更新它。此列可帮助确定某些语句无法重写的原因。

normalized_pattern

此列用于调试和诊断。如果在将规则表加载到内存中时该列存在,则插件会使用模式的规范化形式对其进行更新。如果您尝试确定某些语句无法重写的原因,则此列可能很有用。

重写器查询重写插件过程

将规则添加到 rewrite_rules表中不足以使Rewriter插件使用该规则。还必须调用flush_rewrite_rules()以将表内容加载到插件内存缓存中:

Rewriter插件操作使用存储过程将规则表加载到其内存缓存中,在正常操作下,用户仅调用flush_rewrite_rules()从而将rewrite_rules表的内容加载到Rewriter内存高速缓存中。加载表后,它还会清除查询缓存。

当修改规则表后,需要重新调用此过程以使插件从新表内容更新其缓存:

使用重写插件中定义的语句模式查询相应记录:

SELECT DBA_no, name from DBA_inf where DBA_no =8;

通过使用explain语句查看,当前SQL已经使用了索引

重写插件操作信息

该Rewriter插件通过几个状态变量提供有关其操作的信息:

有关这些变量的说明:

  • Rewriter_number_loaded_rules:成功从rewrite_rules表中加载到内存中以供Rewriter 插件使用的重写插件重写规则的数量。
  • Rewriter_number_reloads:rewrite_rules被加载到Rewriter插件缓存中的次数。
  • Rewriter_number_rewritten_queries:Rewriter查询重写插件自加载以来重写的查询数 。
  • Rewriter_reload_error:是否在最近将rewrite_rules表加载到Rewriter 插件使用的内存高速缓存中时发生错误 。如果值为OFF,则不会发生错误。如果值为,则ON发生错误;检查表的message列rewriter_rules是否有错误消息。

通过调用flush_rewrite_rules()存储过程加载规则表时 ,如果某些规则发生错误,则该CALL 语句会产生错误,并且该插件会将 Rewriter_reload_error状态变量设置为ON:

在这种情况下,请检查rewrite_rules表中是否包含非NULL message列值的行,以查看存在的问题。

重写器插件使用字符集

当rewrite_rules表加载到Rewriter插件中时,插件使用character_set_client系统变量的当前全局值来解释语句 。如果character_set_client随后更改全局 值,则必须重新加载规则表。

客户端的会话character_set_client值必须 与加载规则表时的全局值相同,否则规则匹配将不适用于该客户端。

以上就是MySQL查询重写插件的使用的详细内容,更多关于MySQL查询重写插件的资料请关注我们其它相关文章!

(0)

相关推荐

  • MySQL Like模糊查询速度太慢如何解决

    问题:明明建立了索引,为何Like模糊查询速度还是特别慢? Like是否使用索引? 1.like %keyword 索引失效,使用全表扫描.但可以通过翻转函数+like前模糊查询+建立翻转函数索引=走翻转函数索引,不走全表扫描. 2.like keyword% 索引有效. 3.like %keyword% 索引失效,也无法使用反向索引. 使用mysql的explain简单测试如下: explain select * from company_info where cname like '%小%'

  • mysql对于模糊查询like的一些汇总

    1.常见用法: (1)搭配%使用 %代表一个或多个字符的通配符,譬如查询字段name中以大开头的数据: (2)搭配_使用 _代表仅仅一个字符的通配符,把上面那条查询语句中的%改为_,会发现只能查询出下面一条数据: 2.使用like模糊查询会导致索引失效,在数据量大的时候会有性能问题 (1)尽量少以%或者_开头进行模糊查询 通过explain执行计划,我们发现,使用like模糊查询时,如果不以%和_开头查询的话,索引还是有效的 以%或者_开头查询,索引失效 (2)使用覆盖索引 当查询的的条件和查询

  • mysql中模糊查询的四种用法介绍

    下面介绍mysql中模糊查询的四种用法: 1,%:表示任意0个或多个字符.可匹配任意类型和长度的字符,有些情况下若是中文,请使用两个百分号(%%)表示. 比如 SELECT * FROM [user] WHERE u_name LIKE '%三%' 将会把u_name为"张三","张猫三"."三脚猫","唐三藏"等等有"三"的记录全找出来. 另外,如果需要找出u_name中既有"三"又有

  • mysql查询表是否被锁的方法

    具体方法: (推荐教程:mysql数据库学习教程) 查看表被锁状态 # 查询哪些表锁了 show OPEN TABLES where In_use > 0; 查看造成死锁的sql语句 # 查询innodb引擎的运行时信息 show engine innodb status; 查询进程 # 查询所有进程 show processlist; 解锁(删除进程) # 删除进程 kill id; 查看正在锁的事物 # 查看正在锁的事物 SELECT * FROM INFORMATION_SCHEMA.IN

  • mysql show processlist 显示mysql查询进程

    1.进入mysql/bin目录下输入mysqladmin processlist; 2.启动mysql,输入show processlist; 如果有 SUPER 权限,则可以看到全部的线程,否则,只能看到自己发起的线程(这是指,当前对应的MySQL帐户运行的线程). 得到数据形式如下(只截取了三条): mysql> show processlist; +-----+-------------+--------------------+-------+---------+-------+----

  • Mysql| 使用通配符进行模糊查询详解(like,%,_)

    通配符的分类: %百分号通配符: 表示任何字符出现任意次数 (可以是0次). _下划线通配符:表示只能匹配单个字符,不能多也不能少,就是一个字符. like操作符: LIKE作用是指示mysql后面的搜索模式是利用通配符而不是直接相等匹配进行比较. 注意: 如果在使用like操作符时,后面的没有使用通用匹配符效果是和=一致的,SELECT * FROM products WHERE products.prod_name like '1000';只能匹配的结果为1000,而不能匹配像JetPack

  • python查询MySQL将数据写入Excel

    一.概述 现有一个用户表,需要将表数据写入到excel中. 环境说明 mysql版本:5.7 端口:3306 数据库:test 表名:users 表结构如下: CREATE TABLE `users` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `username` varchar(50) COLLATE utf8mb4_bin NOT NULL COMMENT '用户名', `password` varchar(255) CHARACTER SET u

  • MySql设置指定用户数据库查看查询权限

    一.新建用户: 1.执行sql语句新建(推荐): INSERT INTO `mysql`.`user` ( `Host`, `User`, `Password`, `ssl_cipher`, `x509_issuer`, `x509_subject`, `authentication_string` ) VALUES ( '%', -- 允许远程访问 'zhangsan', -- 用户名 '*6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9', -- 明文密码:1

  • mysql分页原理和高效率的mysql分页查询语句

    以前我在mysql中分页都是用的 limit 100000,20这样的方式,我相信你也是吧,但是要提高效率,让分页的代码效率更高一些,更快一些,那我们又该怎么做呢? 第一部分:看一下分页的基本原理: 复制代码 代码如下: mysql explain SELECT * FROM message ORDER BY id DESC LIMIT 10000, 20***************** 1. row **************id: 1select_type: SIMPLEtable: m

  • mysql查询的时候给字段赋默认值操作

    需求 查询某个字段的时候需要给一个字段同样的值. 这个值你可以写死,也可以从数据库获取 1.写死值 SELECT mfr_id AS mfrId, mfr_name AS mfrName, IFNULL(NULL, 587694978080178176) AS suppId FROM mater_prod materProd 查询结果 2.从数据库获取值 SELECT mfr_id AS mfrId, mfr_name AS mfrName, IFNULL(NULL, mfr_id) AS su

  • MySQL里面的子查询实例

    一,子选择基本用法 1,子选择的定义 子迭择允许把一个查询嵌套在另一个查询当中.比如说:一个考试记分项目把考试事件分为考试(T)和测验(Q)两种情形.下面这个查询就能只找出学生们的考试成绩 select * from score where event_id in (select event_id from event where type='T'); 2,子选择的用法(3种)         用子选择来生成一个参考值 在这种情况下,用内层的查询语句来检索出一个数据值,然后把这个数据值用在外层

随机推荐