MySQL内核月报 2014.10-MySQL· 5.7重构·Optimizer Cost Model

简介:

为了生成执行计划,优化器会使用一个基于估算查询执行过程中各种操作开销的成本模型。MySQL优化器有一组在编译时默认指定的“成本常量”(例如CPU算几个因子、IO算几个因子),用于决策执行计划的生成。

从5.7.5开始,优化器在执行计划的生成过程中有了额外的成本估算项可用。这些估算项存在在mysql系统库的server_cost和engine_cost表中,并且任何时候都可以通过修改表中的值来配置这些估算项。这些表存在的目的是,可以通过简单的调整这些表中的成本估算项来影响执行计划的生成,来达到调整执行计划的目的。

两张表的结构和内容如下:

 
 


成本模型的工作方式


可配置的优化器成本模型按如下方式工作:

MySQL Server在启动时读取成本模型表,并且在运行时使用内存中存贮的值。表中任何非NULL的成本估算项的值都会覆盖在代码中写死的默认成本常数,优先参与优化器成本计算。任何NULL值的成本估算项优化器都会认为用户没有指定特定的值,而使用代码中默认的成本常数。

在MySQL运行时,Server可能会重新读取成本表,可以通过动态载入存储引擎或者执行FLUSH OPTIMIZER_COSTS语句来触发。

成本估算表可以让管理员通过简单的方式去调整成本估算项,也可以通过把估算项设置为NULL来恢复原来的内置默认值。优化器使用的是内存中缓存的开销值,所以修改了表中的值后记得用FLUSH OPTIMIZER_COSTS命令让修改生效。

内存中缓存的成本项对当前正在执行的Session是不起效果的,一个Session内执行的Query其成本项的值是不会变动的。即使Server触发了重新读取成本表,任何估算项的变更也只影响后来链接上来的Session。

成本开销表是不参与复制的,只影响修改的本地实例,不会通过复制把开销表的变更复制到备库。


成本模型数据库


优化器成本模型库由mysql系统库下的两张表组成,包含了Query执行过程中一些操作项的成本估算值:

server_cost: Server层一些操作的成本估算项的值

engine_cost: 特定引擎的一些操作的成本估算项的值


server_cost表包含这些字段:

cost_name

成本模型中的成本估算项的名称(不区分大小写)。如果Server无法识别名称,在读取的时候会打一个报错在error log中。

cost_value

成本估算项的值。如果值是非NULL的,那么Server就使用这个值作为成本,否则就用编译时内置的值,DBA可以通过UPDATE这个列来修改响应的成本项。如果Server读到无效的值(例如负数),会在errorlog中打一条Warning。

要覆盖内置的默认值就需要设置一个非NULL值,如果要恢复默认值,就把值重新改为NULL,然后执行FLUSH OPTIMIZER_COSTS 告诉Server重新读取成本表。

last_update

这一行的最后修改时间。

comment

成本项的描述注释。DBA可以利用这个这个列来记录为什么修改了这个成本项的值,用于备查。


server_cost表的主键是server_cost,所以不能创建名称相同的成本项。


Server可以识别server_cost表中如下的cost_name:

disk_temptable_create_cost, disk_temptable_row_cost

内部创建磁盘临时表的成本开销。增加这些成本项的值可以让优化器更偏向于生成不使用磁盘临时表的执行计划。

key_compare_cost

比较记录键值的成本开销。增加这个值可以让执行计划中比较键值的操作成本变的更加昂贵。例如,一个执行计划执行了filesort,那么它的代价会比利用索引避免排序的代价要大得多。

memory_temptable_create_cost, memory_temptable_row_cost

内部创建内存临时表的成本开销。增加这些值可以使得建立内部临时表成本增加,因而优化器会偏向于不使用临时表。

row_evaluate_cost

扫描记录行的成本开销。增加这个会导致执行计划中扫描很多行数据的操作变得更加昂贵,因而执行计划会偏向扫描更少的函数。例如,一个全表扫描会比范围扫描要昂贵的多。


engine_cost 表包含这些列:

engine_name

要应用这个成本项的存储引擎的名称(不区分大小写)。如果这些值是default,那么对所有没在表里指定的存储引擎都会生效。如果Server无法认出引擎名称,会在errorlog输出一条Warning。

device_type

这个成本项适用的设备类型。这个列可以为不同的存储设备指定不同的成本开销,例如SAS盘和SSD盘是不一样的。不过目前,这个信息还没启用,只有0可以设置。

cost_value,last_update,comment

这三列的含义跟server_cost表中的字段含义一样.


engine_cost表的主键是 (cost_name, engine_name, device_type),所以不允许为一个引擎的同一类存储设备创建相同的成本项。


目前Server只识别engine_cost表中的一个cost_name:

io_block_read_cost

这个成本项表示从磁盘读取一个数据的成本。增加这个值会导致执行计划中读取磁盘块会有更高的成本,因此优化器会偏向于读取更少的磁盘块。例如,一个全表扫描会比一个范围扫描读取更少的磁盘块,因此优化器会偏向范围扫描。


相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。   相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情: https://www.aliyun.com/product/rds/mysql 
目录
相关文章
|
关系型数据库 MySQL Java
浅谈订单重构之MySQL分库分表实战篇
浅谈订单重构之MySQL分库分表实战篇
579 0
|
SQL 存储 关系型数据库
【MySQL进阶-06】深入理解mysql的内核查询成本计算
【MySQL进阶-06】深入理解mysql的内核查询成本计算
1278 0
|
关系型数据库 MySQL Java
Django学习二:配置mysql,创建model实例,自动创建数据库表,对mysql数据库表已经创建好的进行直接操作和实验。
这篇文章是关于如何使用Django框架配置MySQL数据库,创建模型实例,并自动或手动创建数据库表,以及对这些表进行操作的详细教程。
1158 0
Django学习二:配置mysql,创建model实例,自动创建数据库表,对mysql数据库表已经创建好的进行直接操作和实验。
|
SQL 存储 关系型数据库
Mysql内核查询成本计算
Mysql内核查询成本计算
|
关系型数据库 MySQL 数据库
MySQL技能完整学习列表——1、数据库基础概念——2、数据库管理系统(DBMS)——3、数据模型(Data Model)
MySQL技能完整学习列表——1、数据库基础概念——2、数据库管理系统(DBMS)——3、数据模型(Data Model)
299 0
|
缓存 关系型数据库 MySQL
高性能 MySQL(九):通过重构查询语句,来解决慢查询
上一篇我们讲到通到优化数据访问,来解决慢查询问题,这是解决慢查询的基础。但有时我们的查询过于复杂,导致查询速度慢,我们不得不重构查询。今天就来讲下重构查询的几种方式。
465 0
|
存储 SQL JSON
MySQL optimizer_trace cost量化分析
MySQL optimizer_trace cost量化分析
456 0
|
存储 SQL 网络协议
Django model 层之Models与Mysql数据库小结2
Django model 层之Models与Mysql数据库小结
390 0

相关产品

  • 云数据库 RDS MySQL 版
  • 推荐镜像

    更多