查询重写 - 非官方 MySQL 8.0 优化指南 - 学习笔记

MySQL 服务端支持重写语句功能。你可以认为这类似用正则表达式去匹配特定的语句并重写。

这个功能的设计目标之一是让 DBA 们能够在语句中插入查询提示。这缓和了应用自身无法修改语句的情形,例如用到了 ORM 框架,或应用是私有的。

需要指出的是,说查询重写类似于正则表达式,其实比正则高效得多。当语句被分析时,预编译语句会与内部的需要重写的语句哈希表对照检查。如果一个语句需要重写,服务端会重复这一步骤并重新解析该查询。这意味着不需要重写的语句的处理代价很低,并且需要重写的语句需要解析两次。

例子33:服务端通过重写,改变了查询

# 在命令行中,安装查询重写插件
mysql -u root -p < install_rewriter.sql
-- 在 MySQL 中添加重写规则并应用
INSERT INTO query_rewrite.rewrite_rules(pattern_database, pattern, replacement) VALUES (
"world",
"SELECT * FROM Country WHERE population > ? AND continent=?",
"SELECT * FROM Country WHERE population > ? AND continent=? LIMIT 1"
);
CALL query_rewrite.flush_rewrite_rules();

-- 每次当重写事件发生时,会触发警告信息
SELECT * FROM Country WHERE population > 5000000 AND continent='Asia';

-- 从警告信息可以看到重写结果
SHOW WARNINGS;
Query 'SELECT * FROM Country WHERE population > 5000000 AND continent='Asia'' 
rewritten to 'SELECT * FROM Country WHERE population > 5000000 AND continent='Asia' LIMIT 1' by a query rewrite plugin

-- 查询重写规则
SELECT * FROM query_rewrite.rewrite_rules


*************************** 1. row ***************************
                id: 2
           pattern: SELECT * FROM Country WHERE population > ? AND continent=?
  pattern_database: world
       replacement: SELECT * FROM Country WHERE population > ? AND continent=? LIMIT 1
           enabled: YES
           message: NULL
    pattern_digest: 88876bbb502cef6efddcc661cce77deb
normalized_pattern: select `*` from `world`.`Country` where ((`population` > ?) and (`continent` = ?))

提示

MySQL 服务端支持查询重写插件。这里展示的例子是一个后置解析重写插件(Rewriter),某些查询可能需要一个前置解析插件。更多信息可以在 MySQL 官方手册中找到:
https://dev.mysql.com/doc/refman/5.7/en/rewriter-query-rewrite-plugin.html

译自:
Query Rewrite – The Unofficial MySQL 8.0 Optimizer Guide

    原文作者:mokou591
    原文地址: https://www.jianshu.com/p/926f0c751f8d
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞