You need to enable JavaScript to run this app.
文档中心
云数据库 veDB MySQL 版

云数据库 veDB MySQL 版

复制全文
下载 pdf
内核功能
Statement Outline
复制全文
下载 pdf
Statement Outline
本文介绍如何使用 Statement outline 功能。
支持版本
  • MySQL 8.0 版本,且内核版本为 3.0.6.1 及以上。
  • MySQL 5.7 版本,且内核版本为 2.0.6.2 及以上。
背景信息
Statement outline
实例运行过程中,一些 SQL 的执行计划可能会发生非预期的变化,造成稳定性风险。
例如:
  1. 在线业务使用 order by limit n 的用法,在 n 值比较小的时候频繁出现执行计划变动影响性能,
  1. 数据量变化时,统计数据也会发生改变。这些变化可能引起优化器的代价选择出现错误判断,选择了非最优的索引。
临时解决办法如实例通过调整 optimizer_switch 参数,或者通过修改业务 SQL 添加 hint 来绑定执行计划,对业务都不够友好。而 Statement outline 功能可将 SQL 的执行计划与 SQL 查询模板绑定,用户无需修改 SQL 即可将查询计划固化,避免出现上述风险。
术语说
缩略语
英文全名
中文解释
Outline
Statement outline
执行计划固化,用于解决生产环境中 SQL 语句的执行计划经常会发生改变,而导致数据库不稳定的问题。
Package
Native package procedure framework
原生工具包,是一组预定义的存储过程(stored procedure)的逻辑集合,方便使用一个领域的相关存储过程。
Digest
SQL Digest
SQL 指纹,在 MySQL 8.0 中默认使用 SHA256 值,每条模板有唯一的值。
Digest Text
SQL Digest Text
SQL 模板,将 SQL 参数去除后的 SQL 语句。
相关参数
参数名
级别
取值范围
默认值
描述
opt_outline_enabled
GLOBAL
[ON|OFF]
ON
用于设置 Statement outline 功能的开启与关闭。
前提条件
创建实例,且实例状态为运行中
Hint
MySQL 通过 hint 提供了语句维度的优化器控制,通过将 hint 添加至 SQL 语句,即可对 SQL 查询器的决策进行干预:
SELECT /*+ NO_RANGE_OPTIMIZATION(t3 PRIMARY, f2_idx) */ f1 FROM t3 WHERE f1 > 30 AND f1 < 33;
SELECT /*+ BKA(t1) NO_BKA(t2) */ * FROM t1 INNER JOIN t2 WHERE ...;
SELECT /*+ NO_ICP(t1, t2) */ * FROM t1 INNER JOIN t2 WHERE ...;
SELECT /*+ SEMIJOIN(FIRSTMATCH, LOOSESCAN) */ * FROM t1 ...;
EXPLAIN SELECT /*+ NO_ICP(t1) */ * FROM t1 WHERE ...;
SELECT /*+ MERGE(dt) */ * FROM (SELECT * FROM t1) AS dt;
INSERT /*+ SET_VAR(foreign_key_checks=OFF) */ INTO t2 VALUES(2);
Statement outline 功能支持把两类 Hint 绑定至 SQL 模板中,从而达到查询计划固化的效果。支持的 Hint 类型与 MySQL 一致:
SQL 语法接口
云数据库 veDB MySQL 版的内置了 Outline 相关的原生存储过程(Native Package)工具包,用户可通过调用 dbms_outline 相关接口进行 Outline 的操作。
insert_optimizer_outline
  • 描述:增加 Optimizer Hints。
  • 语法:
  • CALL dbms_outline.insert_optimizer_outline('<Schema_name>','<Digest>','<Query_block>','<Hint>','<Query>');
  • 参数说明:
  • 参数
    说明
    Schema_name
    数据库名称。
    说明
    通过添加空<Schema_name>: '',可将 Outline 应用于所有匹配的 Schema。
    Digest
    查询对应的 SQL 指纹。
    Query_Block
    需要应用该 Hint 的关键字(如 SELECTUPDATE 等)编号,从 1 开始。
    Hint
    Hint 表示完整的 Hint 字符串,例如 /*+ NO_ICP(t1, t2) */
    Query
    需要添加 Statement outline 的原始 SQL 语句。
说明
  • Digest 和 Query(原始 SQL语句)可以任选其一。如果填写 Query,dbms_outline 会计算指纹(Digest)和 SQL 模板(Digest_text)。
  • Query 语句中需要使用引号时,需要在 query 语句中给需要添加引号的部分添加单引号,并使用双引号包围 query。
  • 示例:
  • CALL dbms_outline.insert_optimizer_outline('outline_db', '', 1, '/*+ MAX_EXECUTION_TIME(1000) */', 'SELECT * FROM t1 WHERE id = 1');
insert_index_outline
  • 描述:增加 Index Hints。
  • 语法:
  • CALL dbms_outline.insert_index_outline('<Schema_name>','<Digest>','<Position>','<Type>','<Hint>','<Scope>','<Query>');
  • 参数说明
  • 参数
    说明
    Schema_name
    数据库名称。
    说明
    通过添加空<Schema_name>: '',可将 Outline 应用于所有匹配的 Schema。
    Digest
    查询对应的SQL 指纹。
    Position
    需要应用该 Hint 的表的位置,从1开始
    Type
    Index Hint 类型。取值为 USE INDEXFORCE INDEXIGNORE INDEX
    Hint
    索引名字的列表, 例如 idx_1,idx_2
    Scope
    分为如下三类:
    • FOR GROUP BY
    • FOR ORDER BY
    • FOR JOIN
    说明
    空串表示所有类型的 Index Hints。
    Query
    需要添加 Statement outline 的原始 SQL 语句。
说明
  • Digest 和 Query(原始 SQL 语句)可以任选其一。如果填写 Query,dbms_outline 会计算指纹(Digest)和 SQL 模板(Digest_text)。
  • Query 语句中需要使用引号时,需要在 query 语句中给需要添加引号的部分添加单引号,并使用双引号包围 query。
  • 示例:
  • -- 使用原始 SQL 语句
    CALL dbms_outline.insert_index_outline('outline_db', '', 1, 'FORCE INDEX', 'idx_1', '',"SELECT * FROM t1 WHERE t1.col1 = 1 AND t1.col2 = 'mytest'");
    -- 使用 SQL 指纹
    CALL dbms_outline.insert_index_outline('outline_db', 'b4369611be7ab2d27c85897632576a04bc08f50b928a1d735b62d0a140628c4c', 1, 'USE INDEX', 'idx_1', '', "");
check_outline
  • 描述:验证 SQL 语句 Statement outline 的生效情况,如果找到了匹配值,该 SQL 模板将会应用指定的 Hint。
  • 语法:
  • CALL dbms_outline.check_outline('<Schema_name>', '<Query>');
  • 参数说明:
  • 参数
    说明
    Schema_name
    数据库名称。
    说明
    通过添加空 <Schema_name>: '',可将 Outline 应用于所有匹配的 Schema。
    Query
    需要添加 Statement outline 的原始 SQL 语句。
  • 示例:
  • CALL dbms_outline.check_outline('outline_db', "SELECT * FROM t1 WHERE t1.col1 =1 AND t1.col2 ='mytest'");
    +------------+------------------------------------------------------------------+------------+------------+-------+---------------------+
    | SCHEMA | DIGEST | BLOCK_TYPE | BLOCK_NAME | BLOCK | HINT |
    +------------+------------------------------------------------------------------+------------+------------+-------+---------------------+
    | outline_db | b4369611be7ab2d27c85897632576a04bc08f50b928a1d735b62d0a140628c4c | TABLE | t1 | 1 | USE INDEX (`idx_1`) |
    +------------+------------------------------------------------------------------+------------+------------+-------+---------------------+
  • Explain:
  • 通过 EXPLAIN 语句也可以查看 Outline 是否生效。
  • explain select * from t1 where t1.col1 =1 and t1.col2 ='mytest';
    +----+-------------+-------+------------+------+---------------+-------+---------+-------+------+----------+-------------+
    | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
    +----+-------------+-------+------------+------+---------------+-------+---------+-------+------+----------+-------------+
    | 1 | SIMPLE | t1 | NULL | ref | idx_1 | idx_1 | 5 | const | 1 | 100.00 | Using where |
    +----+-------------+-------+------------+------+---------------+-------+---------+-------+------+----------+-------------+
    1 row in set, 1 warning (0.00 sec)
    mysql> show warnings;
    +-------+------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    | Level | Code | Message |
    +-------+------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    | Note | 1003 | /* select#1 */ select `outline_db`.`t1`.`id` AS `id`,`outline_db`.`t1`.`col1` AS `col1`,`outline_db`.`t1`.`col2` AS `col2` from `outline_db`.`t1` USE INDEX (`idx_1`) where ((`outline_db`.`t1`.`col1` = 1) and (`outline_db`.`t1`.`col2` = 'mytest')) |
    +-------+------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    1 row in set (0.00 sec)
  • Explain Analyze:
  • MySQL 8.0 支持了 EXPLAIN ANALYZE 语法,允许用户实际执行查询并给出详细的执行信息。适用于需要对查询性能进行详细分析的场景。开启 Statement Outline 后,您可以在 Explain Analyze 中验证 outline 的性能。
  • mysql> explain analyze SELECT * FROM t1 WHERE t1.col1 =1 AND t1.col2 ='mytest';
    +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    | EXPLAIN |
    +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    | -> Filter: (t1.col2 = 'mytest') (cost=1.10 rows=1) (actual time=0.100..0.100 rows=0 loops=1) |
    | -> Index lookup on t1 using idx_1 (col1=1) (cost=1.10 rows=1) (actual time=0.099..0.099 rows=0 loops=1) |
    +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    1 row in set (0.00 sec)
display_outline
  • 描述:查看系统中保存 Statement outline 以及生效情况。
  • 语法:
  • CALL dbms_outline.display_outline();
  • 示例:
  • CALL dbms_outline.display_outline();
    +------+------------+------------------------------------------------------------------+-----------+-------+------+--------------------+------+----------+-----------------------------------------------------------------------------------------------------------------+
    | ID | SCHEMA | DIGEST | TYPE | SCOPE | POS | HINT | HIT | OVERFLOW | DIGEST_TEXT |
    +------+------------+------------------------------------------------------------------+-----------+-------+------+--------------------+------+----------+-----------------------------------------------------------------------------------------------------------------+
    | 1 | outline_db | ab234071d1d3af13a775f45b532639203e1aa8c3ec63b289a75b9fb862c61c4c | USE INDEX | | 1 | idx_1 | 0 | 0 | SELECT * FROM `t1` WHERE `t1` . `id` = ? UNION SELECT * FROM `t1` WHERE `t1` . `col1` = ? AND `t1` . `col2` = ? |
    | 2 | outline_db | ab234071d1d3af13a775f45b532639203e1aa8c3ec63b289a75b9fb862c61c4c | OPTIMIZER | | 2 | /*+ QB_NAME(q2) */ | 0 | 0 | SELECT * FROM `t1` WHERE `t1` . `id` = ? UNION SELECT * FROM `t1` WHERE `t1` . `col1` = ? AND `t1` . `col2` = ? |
    +------+------------+------------------------------------------------------------------+-----------+-------+------+--------------------+------+----------+-----------------------------------------------------------------------------------------------------------------+
说明
  • HIT 表示该 Statement outline 命中的次数,
  • OVERFLOW 表示该 Statement outline 只匹配了 schema 和 digest 而没有找到 Query Block 或相应的表的次数。
delete_outline
  • 描述:删除内存和表中的某一条 Statement outline。
  • 语法:
  • CALL dbms_outline.delete_outline(<Id>);
  • 参数说明:
  • 参数
    说明
    Id
    Outline ID。
  • 示例:
  • CALL dbms_outline.delete_outline(2);
  • 如果删除的 Outline 不存在,会返回警告,使用 SHOW WARNINGS 查看警告内容。
  • -- 删除不存在的 outline
    CALL dbms_outline.delete_outline(999999);
    Query OK, 0 rows affected, 2 warnings (0.00 sec)
    SHOW WARNINGS;
    +---------+------+------------------------------------------------+
    | Level | Code | Message |
    +---------+------+------------------------------------------------+
    | Warning | 7521 | Statement outline 999999 is not found in table |
    | Warning | 7521 | Statement outline 999999 is not found in cache |
    +---------+------+------------------------------------------------+
    2 rows in set (0.00 sec)
常见场景
Index Hint
指定使用 t1 表的 idx_1 索引。
CALL dbms_outline.insert_index_outline('outline_db', '', 1, 'USE INDEX', 'idx_1', '',
"select * from t1 where t1.col1 =1 and t1.col2 ='mytest'");
Optimizer Hint
使用 Nested-Loop join
  • 示例
  • CALL dbms_outline.insert_optimizer_outline('outline_db', '', 1, '/*+ BNL(t1,t2) */',
    "select t1.id, t2.id from t1,t2");
    mysql> explain select t1.id, t2.id from t1,t2;
    +----+-------------+-------+------------+-------+---------------+-------+---------+------+------+----------+----------------------------------------------------+
    | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
    +----+-------------+-------+------------+-------+---------------+-------+---------+------+------+----------+----------------------------------------------------+
    | 1 | SIMPLE | t1 | NULL | index | NULL | ind_1 | 5 | NULL | 1 | 100.00 | Using index |
    | 1 | SIMPLE | t2 | NULL | index | NULL | ind_1 | 5 | NULL | 1 | 100.00 | Using index; Using join buffer (Block Nested Loop) |
    +----+-------------+-------+------------+-------+---------------+-------+---------+------+------+----------+----------------------------------------------------+
    2 rows in set, 1 warning (0.01 sec)
    mysql> show warnings;
    +-------+------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    | Level | Code | Message |
    +-------+------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    | Note | 1003 | /* select#1 */ select /*+ BNL(`t1`@`select#1`) BNL(`t2`@`select#1`) */ `outline_db`.`t1`.`id` AS `id`,`outline_db`.`t2`.`id` AS `id` from `outline_db`.`t1` join `outline_db`.`t2` |
    +-------+------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    1 row in set (0.00 sec)
  • 示例说明:
  • BNL 表示 Block Nested Loop,这是一种表连接算法。其核心逻辑是:
  • 将驱动表(如 t1)的数据按块(Block)加载到内存中。
  • 在内存块中逐行与被驱动表(如 t2)的数据进行匹配。
  • 适用于驱动表较小且被驱动表无高效索引的场景。
  • 作用对象 BNL(t1, t2) 表示强制优化器在表 t1t2 的关联操作中采用块嵌套循环连接算法。
子查询(subquery)相关的
  • 设置子查询的 Query block 标识
  • CALL dbms_outline.insert_optimizer_outline('outline_db', '', 2, ' /*+ QB_NAME(subq1) */',
    "SELECT * FROM t1 WHERE t1.col1 IN (SELECT col1 FROM t2)");
  • 使用 SEMIJOIN 相关 HINT
  • CALL dbms_outline.insert_optimizer_outline('outline_db', '', 1, '/*+ SEMIJOIN(@subq1 MATERIALIZATION, DUPSWEEDOUT) */ ',
    "SELECT * FROM t1 WHERE t1.col1 IN (SELECT col1 FROM t2)");
  • 示例说明:
  • SEMIJOIN 表示该提示针对半连接操作,即通过子查询(如 INEXISTS)筛选主表数据时,仅匹配子查询中至少一条相关记录的场景。
  • @subq1 标识需要优化的子查询名称或别名,此处为上一个 Outline 指定的子查询名称。
  • MATERIALIZATION 物化策略:强制将子查询的结果临时存储在内存或磁盘中,避免重复计算。适用于子查询结果集较小但需要多次访问的场景。
  • DUPSWEEDOUT 去重策略:在子查询结果中消除重复值,确保主查询仅匹配唯一值。常用于子查询可能返回重复数据时优化性能。
  • 效果验证
  • mysql> explain SELECT * FROM t1 WHERE t1.col1 IN (SELECT col1 FROM t2);
    +----+--------------+-------------+------------+--------+---------------------+---------------------+---------+--------------------+------+----------+-------------+
    | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
    +----+--------------+-------------+------------+--------+---------------------+---------------------+---------+--------------------+------+----------+-------------+
    | 1 | SIMPLE | t1 | NULL | ALL | ind_1 | NULL | NULL | NULL | 1 | 100.00 | Using where |
    | 1 | SIMPLE | <subquery2> | NULL | eq_ref | <auto_distinct_key> | <auto_distinct_key> | 5 | outline_db.t1.col1 | 1 | 100.00 | NULL |
    | 2 | MATERIALIZED | t2 | NULL | index | ind_1 | ind_1 | 5 | NULL | 1 | 100.00 | Using index |
    +----+--------------+-------------+------------+--------+---------------------+---------------------+---------+--------------------+------+----------+-------------+
    3 rows in set, 1 warning (0.00 sec)
    mysql> show warnings;
    +-------+------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    | Level | Code | Message |
    +-------+------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    | Note | 1003 | /* select#1 */ select /*+ SEMIJOIN(@`subq1` MATERIALIZATION, DUPSWEEDOUT) */ `outline_db`.`t1`.`id` AS `id`,`outline_db`.`t1`.`col1` AS `col1`,`outline_db`.`t1`.`col2` AS `col2` from `outline_db`.`t1` semi join (`outline_db`.`t2`) where (`<subquery2>`.`col1` = `outline_db`.`t1`.`col1`) |
    +-------+------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    1 row in set (0.00 sec)
给语句单独设置运行时变量
  • 可以通过 SET_VAR 单独对语句设置变量。
  • /*+ SET_VAR(<var_name>=<var_value>) */
  • Outline 示例:
  • 设置最大查询时间 MAX_EXECUTION_TIME
  • CALL dbms_outline.insert_optimizer_outline("outline_db", '', 1, '/*+ MAX_EXECUTION_TIME(1000) */',
    "select * from t1 where id = 1");
  • 设置外键约束 foreign_key_checks
  • CALL dbms_outline.insert_optimizer_outline("outline_db", '', 1, '/*+ SET_VAR(foreign_key_checks=OFF) */',
    "select * from t1 where id = 1");
  • 效果验证
  • mysql> explain select * from t1 where id = 1;
    +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+--------------------------------+
    | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
    +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+--------------------------------+
    | 1 | SIMPLE | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | no matching row in const table |
    +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+--------------------------------+
    1 row in set, 1 warning (0.01 sec)
    mysql> show warnings;
    +-------+------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    | Level | Code | Message |
    +-------+------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    | Note | 1003 | /* select#1 */ select /*+ MAX_EXECUTION_TIME(1000) SET_VAR(foreign_key_checks='OFF') */ NULL AS `id`,NULL AS `col1`,NULL AS `col2` from `outline_db`.`t1` where multiple equal(1, NULL) |
    +-------+------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    1 row in set (0.00 sec)
FAQ
veDB MySQL 如何处理互相矛盾的 Outline?
如果用户插入了两条矛盾的 Outline,实际起作用的 hint 由 MySQL 的 hint resolve 逻辑决定。详情请参考 MySQL文档
  • 示例
  • mysql> CALL dbms_outline.display_outline();
    +------+------------+------------------------------------------------------------------+-----------+-------+------+-------------------------------------------------------+------+----------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    | ID | SCHEMA | DIGEST | TYPE | SCOPE | POS | HINT | HIT | OVERFLOW | DIGEST_TEXT |
    +------+------------+------------------------------------------------------------------+-----------+-------+------+-------------------------------------------------------+------+----------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    | 14 | | d9bc7ca4b466e3eff5c35133b62328b340e7996a20c0a3278f44e81908516796 | OPTIMIZER | | 2 | /*+ QB_NAME(subq2) */ | 6 | 0 | SELECT * FROM `db1` . `t1` WHERE `t1` . `col1` IN ( SELECT `col1` FROM `db1` . `t2` ) |
    | 15 | | d9bc7ca4b466e3eff5c35133b62328b340e7996a20c0a3278f44e81908516796 | OPTIMIZER | | 2 | /*+ NO_INDEX(t1) */ | 2 | 0 | SELECT * FROM `db1` . `t1` WHERE `t1` . `col1` IN ( SELECT `col1` FROM `db1` . `t2` ) |
    | 16 | | d9bc7ca4b466e3eff5c35133b62328b340e7996a20c0a3278f44e81908516796 | OPTIMIZER | | 2 | /*+ INDEX(t1) */ | 2 | 0 | SELECT * FROM `db1` . `t1` WHERE `t1` . `col1` IN ( SELECT `col1` FROM `db1` . `t2` ) |
    | 17 | | d9bc7ca4b466e3eff5c35133b62328b340e7996a20c0a3278f44e81908516796 | OPTIMIZER | | 2 | /*+ INDEX(t2) */ | 0 | 0 | SELECT * FROM `db1` . `t1` WHERE `t1` . `col1` IN ( SELECT `col1` FROM `db1` . `t2` ) |
    | 18 | | d9bc7ca4b466e3eff5c35133b62328b340e7996a20c0a3278f44e81908516796 | OPTIMIZER | | 2 | /*+ NO_INDEX(t2) */ | 0 | 0 | SELECT * FROM `db1` . `t1` WHERE `t1` . `col1` IN ( SELECT `col1` FROM `db1` . `t2` ) |
    +------+------------+------------------------------------------------------------------+-----------+-------+------+-------------------------------------------------------+------+----------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    mysql> CALL dbms_outline.check_outline('', 'SELECT * FROM db1.t1 WHERE t1.col1 IN (SELECT col1 FROM db1.t2)');
    +--------+------------------------------------------------------------------+------------+------------+-------+----------------------------------------------------+
    | SCHEMA | DIGEST | BLOCK_TYPE | BLOCK_NAME | BLOCK | HINT |
    +--------+------------------------------------------------------------------+------------+------------+-------+----------------------------------------------------+
    | | d9bc7ca4b466e3eff5c35133b62328b340e7996a20c0a3278f44e81908516796 | QUERY | | 1 | /*+ NO_INDEX(`t1`@`subq2`) INDEX(`t2`@`subq2`) */ |
    | | d9bc7ca4b466e3eff5c35133b62328b340e7996a20c0a3278f44e81908516796 | QUERY | | 2 | /*+ QB_NAME(`subq2`) */ |
    +--------+------------------------------------------------------------------+------------+------------+-------+----------------------------------------------------+
    2 rows in set, 2 warnings (0.00 sec)
    mysql> show warnings;
    +---------+------+-----------------------------------------------------------+
    | Level | Code | Message |
    +---------+------+-----------------------------------------------------------+
    | Warning | 3126 | Hint INDEX(`t1` ) is ignored as conflicting/duplicated |
    | Warning | 3126 | Hint NO_INDEX(`t2` ) is ignored as conflicting/duplicated |
    +---------+------+-----------------------------------------------------------+
    2 rows in set (0.00 sec)
  • 示例说明
  • Query block 2 中只有 t2,但 Outline 指定了对于 t1 的 index,而且对 t2 的 index 同时指定了 NO_INDEX 和 INDEX。这时候虽然所有 hint 都能匹配,但是最后生效的是第一个插入的 Outline:NO_INDEX(t1)INDEX(t2)
  • 如果出现矛盾的 Outline,会返回警告,使用 SHOW WARNINGS 查看警告内容。
Outline 在什么节点添加、生效?
  • Outline 相关管理 SQL 接口只能在主节点执行,调用下列 SQL 接口之后,Outline 的修改自动会同步至所有只读节点并且生效:
  • insert_optimizer_outline
  • insert_index_outline
  • delete_outline
  • Outline 验证以及显示接口可在任意节点执行:
  • display_outline
  • check_outline
开启 Statement outline 后,对数据库性能是否有影响?
开启 Statement outline 后,SQL 执行时会计算一次 SQL 指纹。
对性能几乎无影响,在受 SQL 指纹计算影响最大的 CPU-bound 性能测试中,Outline 对性能的影响 < 3%。
备份恢复会恢复系统中 Outline 吗?
  • 如果您选择了「恢复到新实例」,会从新实例全量恢复实例数据到指定时间点,系统中保存的 Outline 也表将会回到指定时间点的状态。
  • 如果您选择了「恢复到原实例」,您将指定用户库表进行恢复,此时 Outline 将保持原样。
升级 MySQL 版本对 Outline 有何影响?
MySQL 5.7 与 MySQL 8.0 对 SQL 指纹的计算方式不同,因此两个版本的 Outline 互不兼容。
如果您已在 MySQL 5.7 上添加了若干 Outline,在将 MySQL 实例的大版本从 5.7 升级到 8.0 时,云数据库 veDB MySQL 版将自动为您迁移相关 Outline。迁移完成后,生效 Outline 的 SQL 指纹将发生改变。
不同 MySQL 大版本支持的 HINT 类型、优化器决策有较大区别区别,MySQL 5.7 上的 Outline 在 MySQL 8.0 版本中未必是最优,并且可能会失效。我们建议您在在升级后,确认并验证所有 Outline,以免您的 SQL 查询使用了非预期的执行计划。
最近更新时间:2026.08.05 16:02:16
这个页面对您有帮助吗?
有用
有用
无用
无用