Persist plan功能支持在SQL参数化级别使Hints持久化。Query-Blocker功能支持参数化SQL的拦截,实现SQL防火墙的功能。本文适用于AnalyticDB MySQL版3.1.4及以上版本的集群。

功能介绍

在集群级别开启高级优化特性,可能影响范围较大。通过Persist plan设置指定SQL的Hints,可以使Hints只对相同Pattern(即参数化后的SQL)的SQL生效。Persist plan规则支持通过系统表查看和删除。

说明
  • 通过Persist plan设置指定SQL的Hints时,不会执行当前SQL。
  • 相同Pattern指用?替代SQL里的常量,例如SELECT、WHERE中的常量条件,LIMIT m、n等。

语法结构

  • 计算SQL参数化后的Pattern和Sign:PARAMETERIZE $sql
  • 针对指定SQL Pattern,添加Hints:/*+hints*/ PERSIST_PLAN $sql
  • 针对指定SQL Pattern,删除Hints:DELETE_PLAN $sqlDELETE_PLAN_BY_SIGN $Sign
  • 查询指定SQL是否配置过Hints:
    • PERSIST_PLAN_CHECK $sql
    • SELECT * FROM INFORMATION_SCHEMA.KEPLER_PERSIST_PLAN_SUMMARY
  • 查询配置过Hints的所有SQL Pattern:SELECT * FROM INFORMATION_SCHEMA.KEPLER_PERSIST_PLAN_SUMMARY

典型应用:拦截SQL Pattern

使用/*+query_blocker=true*/ persist_plan + SQL,针对指定Pattern拦截同类型的Bad SQL。示例如下:
/*+query_blocker=true*/
PERSIST_PLAN
SELECT t1.c1
FROM t1
    INNER JOIN t2 ON t1.c1 = t2.c1
WHERE t1.c2 < 9999;

Persist Plan示例

  • 计算SQL参数化后的Pattern&Sign
    针对以下SQL计算其对应的Pattern和Sign值,示例如下:
    PARAMETERIZE
    SELECT
      t1.c1
    FROM
      t1
      INNER JOIN t2 ON t1.c1 = t2.c1
    WHERE
      t1.c2 < 9999;
    执行命令的结果如下:
    signsql
    2506ed2c1f53ea59a1ef996a98a50411SELECT t1.c1 FROM t1 INNER JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c2 < ?
  • 针对指定SQL Pattern,添加Hints
    为相同Pattern的SQL,执行nested loop join策略,示例如下:
    /*+nested_loop_join=true*/
    PERSIST_PLAN
    SELECT t1.c1FROM t1
        INNER JOIN t2 ON t1.c1 = t2.c1
    WHERE t1.c2 < 9999;
  • 查询指定SQL是否配置过Hints
    PERSIST_PLAN_CHECK
    SELECT t1.c1
    FROM t1
        INNER JOIN t2 ON t1.c1 = t2.c1
    WHERE t1.c2 < 9999;
    执行命令的结果如下:
    signHintshitAppiledsql
    2506ed2c1f53ea59a1ef996a98a50411nested_loop_join=true12SELECT t1.c1 FROM t1 INNER JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c2 < ?
    说明
    • PERSIST_PLAN_CHECK $sql命令在DMS数据管理服务系统中执行时,执行命令成功,但不会显示上表中的结果。若您想看到具体返回信息,请登录MySQL客户端执行。
    • 返回结果中,hitApplied字段表示创建该规则后被应用的次数,若更新该规则,hitApplied字段会清零,重新开始计数。
  • 查询配置过Hints的所有SQL Pattern
    SELECT * FROM INFORMATION_SCHEMA.KEPLER_PERSIST_PLAN_SUMMARY;
  • 针对指定SQL Pattern,删除Hints
    AnalyticDB MySQL版支持删除指定SQL Pattern的Hints,您可以选择以下任意一种实现方式:
    • 使用DELETE_PLAN $sql命令,删除Hints。
      DELETE_PLAN
      SELECT t1.c1
      FROM t1
          INNER JOIN t2 ON t1.c1 = t2.c1
      WHERE t1.c2 < 9999;
    • 使用DELETE_PLAN_BY_SIGN命令,根据Sign值删除Hints。
      DELETE_PLAN_BY_SIGN 2506ed2c1f53ea59a1ef996a98a50411;
      说明 查询SQL Pattern的Sign值有以下两种方法:
      • 通过PARAMETERIZE $sql,在返回结果中查看Sign值。
      • 通过SELECT * FROM INFORMATION_SCHEMA.KEPLER_PERSIST_PLAN_SUMMARY,在返回结果中查看Sign值。