sql执行过程分析optimizer tracing

介绍

mysql从5.6的版本开始提供optimizer tracing功能,开发者可以通过该功能查看mysql的sql解释器的整个执行过程。

快速使用

# Turn tracing on (it's off by default):
SET optimizer_trace="enabled=on";
SELECT ...; # your query here
SELECT * FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE;
# possibly more queries...
# When done with tracing, disable it:
SET optimizer_trace="enabled=off";

示例

表结构

创建一个如下测试表,给nameage加上索引。

CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(35) NOT NULL,
  `age` int(11) NOT NULL,
  `city` varchar(100) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `name` (`name`) USING BTREE,
  KEY `age` (`age`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;

explain

explain select * from user where name = 'tom' and age = 23 order by city;
+----+-------------+-------+------------+-------------+---------------+----------+---------+------+------+----------+--------------------------------------------------------+
| id | select_type | table | partitions | type        | possible_keys | key      | key_len | ref  | rows | filtered | Extra                                                  |
+----+-------------+-------+------------+-------------+---------------+----------+---------+------+------+----------+--------------------------------------------------------+
|  1 | SIMPLE      | user  | NULL       | index_merge | name,age      | name,age | 107,4   | NULL |    1 |      100 | Using intersect(name,age); Using where; Using filesort |
+----+-------------+-------+------------+-------------+---------------+----------+---------+------+------+----------+--------------------------------------------------------+

explain显示mysql同时使用了nameage两个索引(索引合并index_merge)。

optimizer trace

SET optimizer_trace="enabled=on";
select * from user where name = 'tom' and age = 23 order by city;
SELECT * FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE;
SET optimizer_trace="enabled=off";
{
    "steps": [
        {
            "join_preparation": {
                "select#": 1,
                "steps": [
                    {
                        "expanded_query": "/* select#1 */ select `user`.`id` AS `id`,`user`.`name` AS `name`,`user`.`age` AS `age`,`user`.`city` AS `city` from `user` where ((`user`.`name` = 'tom') and (`user`.`age` = 23)) order by `user`.`city`"
                    }
                ]
            }
        },
        {
            "join_optimization": {
                "select#": 1,
                "steps": [
                    {
                        "condition_processing": {
                            "condition": "WHERE",
                            "original_condition": "((`user`.`name` = 'tom') and (`user`.`age` = 23))",
                            "steps": [
                                {
                                    "transformation": "equality_propagation",
                                    "resulting_condition": "((`user`.`name` = 'tom') and multiple equal(23, `user`.`age`))"
                                },
                                {
                                    "transformation": "constant_propagation",
                                    "resulting_condition": "((`user`.`name` = 'tom') and multiple equal(23, `user`.`age`))"
                                },
                                {
                                    "transformation": "trivial_condition_removal",
                                    "resulting_condition": "((`user`.`name` = 'tom') and multiple equal(23, `user`.`age`))"
                                }
                            ]
                        }
                    },
                    {
                        "substitute_generated_columns": {}
                    },
                    {
                        "table_dependencies": [
                            {
                                "table": "`user`",
                                "row_may_be_null": false,
                                "map_bit": 0,
                                "depends_on_map_bits": []
                            }
                        ]
                    },
                    {
                        "ref_optimizer_key_uses": [
                            {
                                "table": "`user`",
                                "field": "name",
                                "equals": "'tom'",
                                "null_rejecting": false
                            },
                            {
                                "table": "`user`",
                                "field": "age",
                                "equals": "23",
                                "null_rejecting": false
                            }
                        ]
                    },
                    {
                        "rows_estimation": [    // 预估不同表访问方法的访问成本
                            {
                                "table": "`user`",
                                "range_analysis": {
                                    "table_scan": { // 全表扫描的行数和成本
                                        "rows": 5,
                                        "cost": 4.1
                                    },
                                    "potential_range_indexes": [ // 分析可能使用的索引
                                        {   // 主键索引不可用
                                            "index": "PRIMARY",
                                            "usable": false,
                                            "cause": "not_applicable"
                                        },
                                        { // name索引可用
                                            "index": "name",
                                            "usable": true,
                                            "key_parts": [
                                                "name",
                                                "id"
                                            ]
                                        },
                                        {   // age索引可用
                                            "index": "age",
                                            "usable": true,
                                            "key_parts": [
                                                "age",
                                                "id"
                                            ]
                                        }
                                    ],
                                    "setup_range_conditions": [],
                                    "group_index_range": {
                                        "chosen": false,
                                        "cause": "not_group_by_or_distinct"
                                    },
                                    "analyzing_range_alternatives": { // 分析各种可能使用的索引的成本
                                        "range_scan_alternatives": [
                                            {
                                                "index": "name",
                                                "ranges": [
                                                    "tom <= name <= tom"
                                                ],
                                                "index_dives_for_eq_ranges": true,
                                                "rowid_ordered": true,
                                                "using_mrr": false,
                                                "index_only": false,    // 是否索引覆盖
                                                "rows": 2,  // 使用该索引获取的记录条数
                                                "cost": 3.41,   // 使用该索引的成本
                                                "chosen": true  // 是否使用该索引
                                            },
                                            {
                                                "index": "age",
                                                "ranges": [
                                                    "23 <= age <= 23"
                                                ],
                                                "index_dives_for_eq_ranges": true,
                                                "rowid_ordered": true,
                                                "using_mrr": false,
                                                "index_only": false,
                                                "rows": 2,
                                                "cost": 3.41,
                                                "chosen": false,
                                                "cause": "cost"
                                            }
                                        ],
                                        "analyzing_roworder_intersect": {   // 分析使用索引合并的成本
                                            "intersecting_indexes": [
                                                {
                                                    "index": "name",
                                                    "index_scan_cost": 1.0135,
                                                    "cumulated_index_scan_cost": 1.0135,
                                                    "disk_sweep_cost": 1.75,
                                                    "cumulated_total_cost": 2.7635,
                                                    "usable": true,
                                                    "matching_rows_now": 2,
                                                    "isect_covering_with_this_index": false,
                                                    "chosen": true
                                                },
                                                {
                                                    "index": "age",
                                                    "index_scan_cost": 1.001,
                                                    "cumulated_index_scan_cost": 2.0145,
                                                    "disk_sweep_cost": 0,
                                                    "cumulated_total_cost": 2.0145,
                                                    "usable": true,
                                                    "matching_rows_now": 0.8,
                                                    "isect_covering_with_this_index": false,
                                                    "chosen": true
                                                }
                                            ],
                                            "clustered_pk": {
                                                "clustered_pk_added_to_intersect": false,
                                                "cause": "no_clustered_pk_index"
                                            },
                                            "rows": 1,
                                            "cost": 2.0145,
                                            "covering": false,
                                            "chosen": true
                                        }
                                    },
                                    "chosen_range_access_summary": {    // 最佳查询方案
                                        "range_access_plan": {
                                            "type": "index_roworder_intersect",
                                            "rows": 1,
                                            "cost": 2.0145,
                                            "covering": false,
                                            "clustered_pk_scan": false,
                                            "intersect_of": [
                                                {
                                                    "type": "range_scan",
                                                    "index": "name",
                                                    "rows": 2,
                                                    "ranges": [
                                                        "tom <= name <= tom"
                                                    ]
                                                },
                                                {
                                                    "type": "range_scan",
                                                    "index": "age",
                                                    "rows": 2,
                                                    "ranges": [
                                                        "23 <= age <= 23"
                                                    ]
                                                }
                                            ]
                                        },
                                        "rows_for_plan": 1,
                                        "cost_for_plan": 2.0145,
                                        "chosen": true
                                    }
                                }
                            }
                        ]
                    },
                    {
                        "considered_execution_plans": [
                            {
                                "plan_prefix": [],
                                "table": "`user`",
                                "best_access_path": {
                                    "considered_access_paths": [
                                        {
                                            "access_type": "ref",
                                            "index": "name",
                                            "rows": 2,
                                            "cost": 2.4,
                                            "chosen": true
                                        },
                                        {
                                            "access_type": "ref",
                                            "index": "age",
                                            "rows": 2,
                                            "cost": 2.4,
                                            "chosen": false
                                        },
                                        {
                                            "rows_to_scan": 1,
                                            "access_type": "range",
                                            "range_details": {
                                                "used_index": "intersect(name,age)"
                                            },
                                            "resulting_rows": 1,
                                            "cost": 2.2145,
                                            "chosen": true,
                                            "use_tmp_table": true
                                        }
                                    ]
                                },
                                "condition_filtering_pct": 100,
                                "rows_for_plan": 1,
                                "cost_for_plan": 2.2145,
                                "sort_cost": 1,
                                "new_cost_for_plan": 3.2145,
                                "chosen": true
                            }
                        ]
                    },
                    {
                        "attaching_conditions_to_tables": {
                            "original_condition": "((`user`.`age` = 23) and (`user`.`name` = 'tom'))",
                            "attached_conditions_computation": [],
                            "attached_conditions_summary": [
                                {
                                    "table": "`user`",
                                    "attached": "((`user`.`age` = 23) and (`user`.`name` = 'tom'))"
                                }
                            ]
                        }
                    },
                    {
                        "clause_processing": {
                            "clause": "ORDER BY",
                            "original_clause": "`user`.`city`",
                            "items": [
                                {
                                    "item": "`user`.`city`"
                                }
                            ],
                            "resulting_clause_is_simple": true,
                            "resulting_clause": "`user`.`city`"
                        }
                    },
                    {
                        "refine_plan": [
                            {
                                "table": "`user`"
                            }
                        ]
                    }
                ]
            }
        },
        {
            "join_execution": {
                "select#": 1,
                "steps": [
                    {
                        "filesort_information": [
                            {
                                "direction": "asc",
                                "table": "`user`",
                                "field": "city"
                            }
                        ],
                        "filesort_priority_queue_optimization": {
                            "usable": false,
                            "cause": "not applicable (no LIMIT)"
                        },
                        "filesort_execution": [],
                        "filesort_summary": {
                            "rows": 1,
                            "examined_rows": 1,
                            "number_of_tmp_files": 0,
                            "sort_buffer_size": 261880,
                            "sort_mode": "<sort_key, packed_additional_fields>"
                        }
                    }
                ]
            }
        }
    ]
}
发布了185 篇原创文章 · 获赞 38 · 访问量 21万+

猜你喜欢

转载自blog.csdn.net/sz85850597/article/details/89601485