MySQL8.0 优化器介绍(四)

作者:佚名    发布时间:2024-04-22 14:56:46    浏览:

[返回]

MySQL8.0在优化器上做了很多努力和优化,仍然不足以保证每条sql,都能拥有合理的执行计划,有些情况需要通过hint来干预。MySQL8.0在hint的种类上进行了新增。本篇主要讲我们可以有哪些方法影响优化器。

优化器配置 Configuring the Optimizer

有很多方法影响优化器。

configuration options

mysql.engine_cost , mysql.server_cost 具体表字段的含义,怎么配置,配置后怎么生效的细节见官网。需要注意的是,配置完以上表后,得做一个FLUSH OPTIMIZER_COSTS; 的动作。

另外还有两个重要参数 optimizer_prune_level 、optimizer_search_depth 值得注意。

Optimizer Switches

optimizer switches 是一个复合的option 集。8.0.25 默认的optimizer switches

optimizer switches 尽管可以会话级设置,但大多数情况下,我们都当作一个全局参数在用。

特别是5.7升级8.0,8.0小版本升级的时候,optimizer switches的检查必须作为一个单独项。前面的文章中已经介绍了10多种优化器的策略、算法。更多细节参考(https://dev.mysql.com/doc/refman/8.0/en/switchable-optimizations.html

Optimizer Hints

https://dev.mysql.com/doc/refman/8.0/en/optimizer-hints.html

Optimizer Hints的特性是5.7引入的,并在8.0做了扩展。可以通过hint 来影响查询计划的执行。

Hint 比optimizer switches的选项控制更精细,可以做到query block,table,index 三级。并且支持在查询期间更改配置选项的值,比会话级修改参数更细。比如可以限制一个sql的执行时间:

Table 8.2 Optimizer Hints Available

  • Global: The hint applies to the whole query.
  • Query Block: The hint applies to a group of joins. For example, the top level of the query is a query block; a subquery is another query block. Hints that apply to a query block can in some cases also take the table names for a join to limit the hint to a specific join.
  • Table: The hint applies to a specific table.
  • Index: The hint applies to the use of a specific index.

hint的语法 注意三个点的前后都有一个空格。语法树都比较好看,举例几个比较难懂的语法。

ps:怎么练习 sql 级别的hint的使用?

  1. 多读几遍25种hint的描述。
  2. 拿着一个正常的执行计划做参考,把一个异常的执行计划试着用hint改到期望的计划。
  3. 大多数的hint都是成对出现的,有关,有开两种组合。把一个正常的计划,试着用hint把计划改得糟糕。
  4. 从简单的sql,单表的入手。逐渐过渡到多表,单机,分布式数据库
  5. google MySQL hints 的经验 并实践。

Index Hints

这个大家应该很熟悉,ignore、use、force index

https://dev.mysql.com/doc/refman/8.0/en/resource-groups.html#resource-group-restrictions

对于high-concurrency systems的场景,MySQL8.0 在server 层,提供了一个resource groups 特性。

本系列文章一共4篇,概括地介绍了优化器是怎么工作的,join的优化算法,以及优化 join的方法;以及怎么配置optimizer。

MySQL使用基于成本的优化器,其中估计查询执行的每个部分的成本,并选择总体查询计划以最小化成本。作为优化的一部分,优化器将使用各种转换重写查询,找到最佳连接顺序,并做出其他决定,例如应使用哪些索引。

MySQL 已经有三种基本的join 算法: NL,BNL,HASH JOIN 。HASH JOIN 弥补了NL 在缺少索引,或者索引选择性不佳时,触发的性能问题。同时HASH JOIN 也带来自身的一些性能问题。

重点聚焦了三种join 优化,index_merge 可以使用多个索引来提高效率。MRR 是通过减少随机IO 来提高效率。BKA=BNL+MRR

另外还介绍了多种影响优化器的方法。

一些有意思的链接:

(http://www.unofficialmysqlguide.com/index.html)(https://www.percona.com/blog/count-vs-countcol-in-mysql/)

搜索

平台注册入口