跟踪MYSQL 的查询优化过程方法

 http://dev.mysql.com/doc/internals/en/tracing-example.html

http://blog.chinaunix.net/uid-20785090-id-5597524.html

handle_select()
   mysql_select()
     JOIN::prepare()
       setup_fields()
     JOIN::optimize()            /* optimizer is from here ... */
       optimize_cond()
       opt_sum_query()
       make_join_statistics()
         get_quick_record_count()
         choose_plan()
           /* Find the best way to access tables */
           /* as specified by the user.          */
           optimize_straight_join()
             best_access_path()
           /* Find a (sub-)optimal plan among all or subset */
           /* of all possible query plans where the user    */
           /* controls the exhaustiveness of the search.   */
           greedy_search()
             best_extension_by_limited_search()
               best_access_path()
           /* Perform an exhaustive search for an optimal plan */
           find_best()
       make_join_select()        /* ... to here */
     JOIN::exec()

 

CREATE TABLE `t` (
`a` int(11) NOT NULL,
`b` int(11) DEFAULT NULL,
`c` int(11) NOT NULL,
PRIMARY KEY (`a`),
KEY `b` (`b`),
KEY `ix` (`b`,`c`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 
json格式:

mysql> explain format=json select b from t\G *************************** 1. row ********************** EXPLAIN: { "query_block": { "select_id": 1, "cost_info": { "query_cost": "1.20" }, "table": { "table_name": "t", "access_type": "index", "key": "b", "used_key_parts": [ "b" ], "key_length": "5", "rows_examined_per_scan": 1, "rows_produced_per_join": 1, "filtered": "100.00", "using_index": true, "cost_info": { "read_cost": "1.00", "eval_cost": "0.20", "prefix_cost": "1.20", "data_read_per_join": "16" }, "used_columns": [ "b" ] } } } 1 row in set, 1 warning (0.00 sec)
更加详细的过程生成:

1.set optimizer_trace_max_mem_size=300000;
2.set end_markers_in_json=true;
3.set optimizer_trace="enabled=on";

4.sql语句

5.select trace from information_schema.optimizer_trace\G;
6.set optimizer_trace="enabled=off";


主要分为三个部分 

join_preparation:SQL的准备阶段,sql被格式化
对应函数 JOIN::prepare
  
join_optimization:SQL优化阶段
对应函数JOIN::optimize
 
 join_execution:SQL执行阶段
对应函数:JOIN::exec
 
join_optimization是核心。
下面详细介绍join_optimization的过程:
1)condition_processing阶段,进行where条件处理,分别是相等处理,常量处理,删除冗余条件
2)ref_optimizer_key_uses阶段,查找可进行ref type访问的索引(索引的等值访问)。
3)records_estimation阶段,进行访问开销预估。这个阶段是最复杂的。先处理访问类型(explain select_type字段的值),候选项分别为全表扫描和所有的索引,开销最小的那个胜出。如果你的语句有Group By,那么在group_index_range子阶段确定是否有适用于range 访问的索引。
4)considered_execution_plans节显示了选定的执行计划
5)attaching_conditions_to_tables分析where条件是否可以执行pushdown,应该是再扫描该表时过滤掉。
6)clause_processing阶段分别处理group by, order by从句。



eg:
set optimizer_trace_max_mem_size=300000;
set end_markers_in_json=true;
set optimizer_trace="enabled=on";

mysql> select b from t;

mysql> select trace from information_schema.optimizer_trace\G
*************************** 1. row ***************************
trace: {
  "steps": [
    {
      "join_preparation": {
        "select#": 1,
        "steps": [
          {
            "expanded_query": "/* select#1 */ select `t`.`b` AS `b` from `t`"
          }
        ]
      }
    },
    {
      "join_optimization": {
        "select#": 1,
        "steps": [
          {
            "table_dependencies": [
              {
                "table": "`t`",
                "row_may_be_null": false,
                "map_bit": 0,
                "depends_on_map_bits": [
                ]
              }
            ]
          },
          {
            "rows_estimation": [
              {
                "table": "`t`",
                "table_scan": {
                  "rows": 1,
                  "cost": 1
                }
              }
            ]
          },
          {
            "considered_execution_plans": [
              {
                "plan_prefix": [
                ],
                "table": "`t`",
                "best_access_path": {
                  "considered_access_paths": [
                    {
                      "rows_to_scan": 1,
                      "access_type": "scan",
                      "resulting_rows": 1,
                      "cost": 1.2,
                      "chosen": true
                    }
                  ]
                },
                "condition_filtering_pct": 100,
                "rows_for_plan": 1,
                "cost_for_plan": 1.2,
                "chosen": true
              }
            ]
          },
          {
            "attaching_conditions_to_tables": {
              "original_condition": null,
              "attached_conditions_computation": [
              ],
              "attached_conditions_summary": [
                {
                  "table": "`t`",
                  "attached": null
                }
              ]
            }
          },
          {
            "refine_plan": [
              {
                "table": "`t`"
              }
            ]
          }
        ]
      }
    },
    {
      "join_explain": {
        "select#": 1,
        "steps": [
        ]
      }
    }
  ]
}
1 row in set (0.00 sec)

set optimizer_trace="enabled=off";

 

select trace into dumpfile "json.txt" from information_schema.optimizer_trace;

 

posted @ 2016-06-23 11:14  zengkefu  阅读(660)  评论(0编辑  收藏  举报