zoukankan      html  css  js  c++  java
  • 跟踪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 tG *************************** 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_traceG;
    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_traceG
    *************************** 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;
  • 相关阅读:
    ROSBAG的使用以及TF_OLD_DATA问题
    cmake 编译安装库到指定目录
    QT 文件夹内文件查询与删除
    数组直接写入vector向量的方法与问题
    github上下载开源项目
    组件
    对象(二)
    对象(一)
    事件
    rem 、em
  • 原文地址:https://www.cnblogs.com/zengkefu/p/5610019.html
Copyright © 2011-2022 走看看