八. MySQL 成本计算与执行优化器优化步骤

目录

  • 一. MySQL 的成本计算
  • 二. 执行优化相关
    • 配置开启"优化追踪命令"
    • MySQL 执行优化器的优化步骤
      • 1. condition_processing 处理搜索条件优化阶段
      • 2. rows_estimation 分析业务SQL优化阶段

一. MySQL 的成本计算

  1. mysql在查询数据时考虑比较重要的两个成本: io成本与cup成本
  1. 将数据由磁盘加载到内存的过程称为io成本,读取一页的数据到内存io成本为1.0
  2. 数据加载到内存后,mysql在内存对数据的读取,解析,计算过滤,排序等相关处理称为cup成本,当通过内存检测一次数据满足执行sql的条件cpu成本为0.2
  1. 全表扫描时的执行过程: 实际就是将聚簇索引加载到内存(也就是实际数据),然后检查是否满足条件,然后将满足过滤条件的数据加入到结果集, 那么全表扫描时mysql所需要的io成本, cup成本怎么计算
  1. io成本: 聚簇索引占用页数1.0+1.1(微调数), cpu成本: 数据条数0.2+1.0(微调数)
    2.mysql中提供了专门的命令查看表的统计信息: 查看所有表"show table status;" 查看指定表"show table status like ‘表名’ ", 返回数据中rows表示数据行数(估计值), Data_length表示当前表数据占用的字节数, 聚簇索引一页16k, Data_length/16/1024获取到当前数据占用的页数
  1. 通过explain 查看执行成本

“explain format=json 实际执行的sql语句” 该方式比普通explain会多返回一些数据,其中query_cost的值就是执行当前sql所需要io成本+cpu成本,继续寻找会发现一个const_info内部保存了详细的执行成本
八. MySQL 成本计算与执行优化器优化步骤_第1张图片

二. 执行优化相关

配置开启"优化追踪命令"

  1. mysql在5.6版本后提供了"优化追踪命令",可以更直观的看到mysql优化后执行的sql, 但是需要配置开启
  1. "show variables like ‘optimizer_trace’ " : 查看mysql是否开启优化追踪
  2. "set optimizer_trace=“enabled=on” ": 开启优化追踪
  3. 执行实际的业务sql, 当业务sql执行完毕后,mysql会将该sql的分析结果存储到一张系统表中,其中就包括优化步骤
  4. “select * from information_schema.optimizer_trace” 查看mysql对业务sql执行计划分析的全过程,返回数据解释:

QUERY: 实际执行的sql
TRACE: 整个执行计划优化分析生成的json文本, 在TRACE中包含执行sql时的三个阶段: “join_preparation 准备阶段”, “join_optimization 优化阶段”, “join_execution 执行阶段”
其中重点关注TRACE下的"join_optimization 优化阶段"

MySQL 执行优化器的优化步骤

  1. mysql在执行前会通过执行计划计算执行成本,选择一个性能最优的路径执行,这也就是执行优化器优化的步骤
  1. 根据搜索条件,找出所有可能使用的索引
  2. 计算全表扫描的执行成本
  3. 计算通过不同索引执行的执行成本
  4. 对比各种执行方案,选择最优执行路径.
  1. 通过TRACE下的"join_optimization 优化阶段",了解到优化阶段通常经过一些几个步骤
  1. 第一步: condition_processing: 处理搜索条件, 可以简单理解为处理where后的一系列条件
  2. 第二步: substitute_generated_columns: 替换虚拟生成列,注意该步骤是5.7以后出现的新特性
  3. 第三步: table_dependencies: 分析表的依赖信息
  4. 第四步:重点 rows_estimation: 分析业务sql的不同执行路径,执行成本, 选择最优路径

1. condition_processing 处理搜索条件优化阶段

  1. condition_processing: 处理搜索条件, 下的详细步骤解释: (condition_processing下存在"original_condition"该key中记录了执行的业务sql,where后的原始条件, 对于原始条件mysql会进行一定的优化,通常情况下可能出现以下几个步骤)
  1. equality_propagation等值传递转换: 例如"where a=1+5" 经过该步骤后会优化为"where a=6"
  2. constant_propagation常量传递转换:
  3. trivial_condition_removal去除没用的条件: 例如 “where 1=1” 永远为true, 经过mysql分析后可能就把这个条件给去掉了
    八. MySQL 成本计算与执行优化器优化步骤_第2张图片

2. rows_estimation 分析业务SQL优化阶段

  1. rows_estimation: 分析业务sql的不同执行路径,执行成本,选择最优路径
  1. 第一步: table_scan分析全表扫描,记录如果业务sql通过全部扫描方式查询数据时,需要扫描的行数rows, 消耗的总成本cost
  2. 第二步: potential_range_indexes分析sql能否命中索引,获取到能够命中的索引,内部又细分为主键索引, 普通索引,联合索引,如果命中索引index下存储的是命中的索引名,usable返回true,
  3. 第三步: range_alternatives 上一步骤拿到了能够命中的索引,当前步骤针对每个能够命中的索引,分析业务sql如果使用该索引获取数据时需要扫描的行数,消耗的总成本,能否使用index_dive索引精确模式扫描数据,mrr访问磁盘时能否顺序访问(不使用随机访问),其中"chosen"中保存了实际有没有实际该索引,false表示没有使用,"cause"中保存了没有使用的原因,如果存储了"cost"表示成本原因所以没采用
    八. MySQL 成本计算与执行优化器优化步骤_第3张图片
  4. 第四步: analyzing_roworder_intersect 分析是否使用了索引合并,usable为false表示没有,cause中存储了没有使用的原因
  5. 第五步: chosen_range_access_summary针对以上索引分析进行统计汇总: 上一步骤中对所有能够命中的索引分析了一遍,当前步骤会选择一个最优的,"index"中存储了应该使用哪个索引, "type"扫描类型,"rows"影响的函数, "ranges"扫描范围,"rows_for_plan"扫描行数,"cost_for_plan"消耗总成本,"chosen"是否选择该索引,true选择
    八. MySQL 成本计算与执行优化器优化步骤_第4张图片
  6. 第六步: considered_execution_plans 选择执行计划,如果是多表连接查询,该步骤会对多表连接的组合成本进行分析计算
    八. MySQL 成本计算与执行优化器优化步骤_第5张图片
  7. 第七步: attaching_conditions_to_tables 尝试给执行的业务sql添加其它执行条件,判断是否能使用ICP,也就是索引下推
    八. MySQL 成本计算与执行优化器优化步骤_第6张图片
  8. 第八步: refine_plan 最终完善优化
    在这里插入图片描述
  1. 以上的分析可以理解为都只针对单表的
  2. 连表查询的成本计算是单次查询驱动表+多次查询被驱动表成本的和

你可能感兴趣的:(mysql,mysql,数据库,java)