Persist plan and Query-Blocker

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;

    执行命令的结果如下:

    sign

    sql

    2506ed2c1f53ea59a1ef996a98a50411

    SELECT 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;

    执行命令的结果如下:

    sign

    Hints

    hitAppiled

    sql

    2506ed2c1f53ea59a1ef996a98a50411

    nested_loop_join=true

    12

    SELECT 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值。