美文网首页MySQL
Optimizer Trace 优化器输出 - 非官方 MySQ

Optimizer Trace 优化器输出 - 非官方 MySQ

作者: mokou591 | 来源:发表于2019-03-30 09:05 被阅读1次

EXPLAIN 只是展示了查询预定执行计划,而没有展示为什么没选取其他执行策略。没选取其他策略的原因可能让人困惑:

  • 是因为不够匹配(比如,一些优化只能用于特定场景)?
  • 是因为其他策略的代价更高?
  • 如果其他策略的代价更高,会高多少?

OPTIMIZER_TRACE能回答这 3 个问题。它用于提供优化器给出的更具诊断性的信息,此外还有助于在实践中排查问题、理解优化器的代价模型是如何工作的。

例子2:EXPLAIN 展示一个不被使用的索引

ALTER TABLE Country ADD INDEX p (population);

EXPLAIN FORMAT=JSON
SELECT * FROM Country WHERE continent='Asia' and population > 5000000;
{
  "query_block": {
   "select_id": 1,
   "cost_info": {
   "query_cost": "53.80"
   },
   "table": {
   "table_name": "Country",
   "access_type": "ALL",       # 这次查询执行为全表扫描
   "possible_keys": [          
      "p"                      # 即便优化器知道有可用索引!
   ],
   "rows_examined_per_scan": 239,
   "rows_produced_per_join": 15,
   "filtered": "6.46",
   "cost_info": {
      "read_cost": "50.71",
      "eval_cost": "3.09",
      "prefix_cost": "53.80",
      "data_read_per_join": "3K"
   },
   "used_columns": [
      ...
   ],
   "attached_condition": "((`world`.`Country`.`Continent` = 'Asia') and (`world`.`Country`.`Population` > 5000000))"
   }
  }
}

在 例子2 中我们可以看到即便表内有 索引p 也没有使用。EXPLAIN 表明它是一个候选的索引,但没有解释为什么不使用它。要知道原因我们需要用到 OPTIMIZER_TRACE

例子3:OPTIMIZER_TRACE 展示优化器为什么不使用索引

SET optimizer_trace="enabled=on"
SELECT * FROM Country WHERE continent='Asia' and population > 5000000;
SELECT * FROM information_schema.optimizer_trace;
...
         "rows_estimation": [
            {
               "table": "`Country`",
               "range_analysis": {
               "table_scan": {
                  "rows": 239,
                  "cost": 55.9                   # 这是全表扫描的代价
               },
               "potential_range_indexes": [
                  {
                     "index": "PRIMARY",
                     "usable": false,
                     "cause": "not_applicable"
                  },
                  {
                     "index": "p",
                     "usable": true,
                     "key_parts": [
                     "Population",
                     "Code"
                     ]
                  }
               ],
               "setup_range_conditions": [],
               "group_index_range": {
                  "chosen": false,
                  "cause": "not_group_by_or_distinct"
               },
               "analyzing_range_alternatives": {
                  "range_scan_alternatives": [
                     {
                     "index": "p",
                     "ranges": [
                        "5000000 < Population"
                     ],
                     "index_dives_for_eq_ranges": true,
                     "rowid_ordered": false,
                     "using_mrr": false,
                     "index_only": false,
                     "rows": 108,
                     "cost": 130.61,             # 这是使用索引花费的代价
                     "chosen": false,            # 不使用它是因为
                     "cause": "cost"             # 代价比全表扫描还要高!
                     }
                  ],
                  "analyzing_roworder_intersect": {
                     "usable": false,
                     "cause": "too_few_roworder_scans"
                  }
               },
               "analyzing_roworder_intersect": {
                     "usable": false,
                     "cause": "too_few_roworder_scans"
                  }
               }
               }
            }
         ]
...

在 例子3 中range_scan_alternatives表明 索引p 被考虑过,但因代价原因被淘汰:"chosen": false"cause": "cost"。输出信息还提供了使用该索引的预估代价:130.61。和全表扫描的代价 55.9 相比,代价低更好,所以选择了全表扫描。
要解释为什么会这样,我们需要先理解索引是如何减少工作量的。查询 “亚洲中人口多于 500W 的国家”,而在该表数据中,大部分国家都有多于 500W 的人口,优化器认为扫描全表比 “在索引和数据间来回访问” 更快。

在索引和数据间来回访问 VS 扫描全表.png

译自:
Optimizer Trace - The Unofficial MySQL 8.0 Optimizer Guide

相关文章

  • Optimizer Trace 优化器输出 - 非官方 MySQ

    EXPLAIN 只是展示了查询预定执行计划,而没有展示为什么没选取其他执行策略。没选取其他策略的原因可能让人困惑:...

  • Optimizer 优化器

    本文介绍常见的优化器及其作用 1.数据及超参数准备 2. 批训练数据 注:Data.DataLoader ,组合数...

  • Optimizer优化器

    1、Adagrad优化算法(https://www.zhihu.com/question/453599361/an...

  • [Mysql] 查看 OPTIMIZER_TRACE

    The OPTIMIZER_TRACE table provides information produced b...

  • MySql高级之性能分析(四)

    1.MySql Query Optimizer:查询优化器。 ​ 1). Mysql中有专门负责优化SELECT语...

  • 01-08 Optimizers: Buliding a par

    优化器:构建参数化模型 Optimizer: find minimum values of functions b...

  • keras-常用函数

    顺序模型 Sequential 配置学习过程 compile 优化器 optimizer 损失函数 loss 评估...

  • RBO和CBO详解

    RBO和CBO的基本概念 Oracle数据库中的优化器又叫查询优化器(Query Optimizer)。它是SQL...

  • sql优化

    1、 优化器 优化器(Optimizer)是SQL分析和执行的优化工具,它负责生成、制定SQL的执行计划。主要有以...

  • 优化器算法Optimizer

    记: 梯度下降算法 系数更新公式为:不妨设,且损失函数为:则梯度为:对于BGD,n为全体数据量;对于SGD,n为1...

网友评论

    本文标题:Optimizer Trace 优化器输出 - 非官方 MySQ

    本文链接:https://www.haomeiwen.com/subject/xcslbqtx.html