MySQL查询优化器源码分析

作者:king_wangheng   发布日期:2012-05-23 09:32:40
目的
基于之前出现的主从库分别执行相同语句,查询计划和执行时间不同的问题。通过对源代码跟踪和调试,对MySQL的查询优化器进行分析并编写文档,为开发人员和数据库管理人员提供查询SQL语句的建议。
 
基础
MySQL的设计架构在官方文档中给出,如下图所示。该图的具体描述和讲解,请参考官方文档或地址:http://dev.mysql.com/doc/refman/5.1/en/pluggable-storage-overview.html



 

图中Optimizer部分为本文研究的重点,主要对Parser解析之后的SQL,根据统计的数据,对访问代价进行权衡,制定执行计划。查询优化器是MySQL中比较活跃的一部分,代码会经常变动。但整体而言,对查询优化器整体把握和理解之后,其他的版本也基本可以轻松理解。以下内容将通过对MySQL 5.5.20版本的源码进行分析,供大家参考。
 
代码分析
1Parser阶段
查询优化器相关的代码主要在sql/sql_select.cc文件中,而在执行该部分代码时,需要对之前的内容做简要说明。本文从Parser阶段case SQLCOM_SELECT:中调用execute_sqlcom_select()函数开始(参看源码sql/sql_parse.cc:2124行),该函数是实际的sql执行阶段,而sql真正执行需要按照一定的规则去执行。因此,需要先制定一个执行计划。但制定计划不能随便制定,需要有一定的依据。并且不能保证所有人写的SQL都是最优的,也就不能根据SQL就简单制定一个规则。于是,出现了SQL Optimizer,该部分不仅对SQL进行了优化,并且根据优化的结果制定查询的执行计划。最终根据执行计划执行,得到数据结果并返回。从代码看,execute_sqlcom_select()函数做了以上的所有工作。
以下将从execute_sqlcom_select()函数开始,逐层次的分析MySQL的查询优化是如何实现的。
2Optimizer阶段
execute_sqlcom_select()函数中,调用了handle_select()函数,而该函数正是处理SQL查询的“入口函数”。
2.1 函数调用层次
首先,将主要的函数调用层次列出,函数层次以之前的“|”标示,以“>”标示进入函数,以“<”标示退出函数,红色标示为递归调用的函数,绿色和蓝色标示为互斥操作。

| | | | >handle_select
| | | | | >mysql_select/mysql_union
| | | | | | >JOIN::prepare
| | | | | | | >setup_tables
| | | | | | | <setup_tables
| | | | | | | >setup_fields
| | | | | | | <setup_fields
| | | | | | | >setup_without_group
| | | | | | | | >setup_conds
| | | | | | | | <setup_conds
| | | | | | | | >setup_order
| | | | | | | | <setup_order
| | | | | | | | >setup_group
| | | | | | | | <setup_group
| | | | | | | <setup_without_group
| | | | | | | >setup_procedure
| | | | | | | <setup_procedure
| | | | | | <JOIN::prepare
| | | | | | >JOIN::optimize
| | | | | | | >simplify_joins
| | | | | | | <simplify_joins
| | | | | | | >build_bitmap_for_nested_joins
| | | | | | | <build_bitmap_for_nested_joins
| | | | | | | >optimize_cond
| | | | | | | <optimize_cond
| | | | | | | >prune_partitions
| | | | | | | <prune_partitions
| | | | | | | >make_join_statistics
| | | | | | | | >make_select
| | | | | | | | <make_select
| | | | | | | | >get_quick_record_count
| | | | | | | | | >SQL_SELECT::test_quick_select
| | | | | | | | | | >get_mm_tree
| | | | | | | | | | <get_mm_tree
| | | | | | | | | | >get_best_group_min_max
| | | | | | | | | | <get_best_group_min_max
| | | | | | | | | | >get_key_scans_params
| | | | | | | | | | <get_key_scans_params
| | | | | | | | | | >get_best_ror_intersect
| | | | | | | | | | <get_best_ror_intersect
| | | | | | | | | | >get_best_disjunct_quick
| | | | | | | | | | <get_best_disjunct_quick
| | | | | | | | | | >TRP_RANGE::make_quick
| | | | | | | | | | <TRP_RANGE::make_quick
| | | | | | | | | <SQL_SELECT::test_quick_select
| | | | | | | | <get_quick_record_count
| | | | | | | | >choose_plan
| | | | | | | | | >optimize_straight_join
| | | | | | | | | | >best_access_path
| | | | | | | | | | <best_access_path
| | | | | | | | | <optimize_straight_join
| | | | | | | | | >greedy_search
| | | | | | | | | | >best_extension_by_limited_search
| | | | | | | | | | | >best_access_path
| | | | | | | | | | | <best_access_path
| | | | | | | | | | <best_extension_by_limited_search
| | | | | | | | | <greedy_search
| | | | | | | | <choose_plan
| | | | | | | <make_join_statistics
| | | | | | | >get_best_combination
| | | | | | | <get_best_combination
| | | | | | | >make_join_select
| | | | | | | <make_join_select
| | | | | | <JOIN::optimize
| | | | | | >JOIN::exec
| | | | | | | >do_select
| | | | | | | <do_select
| | | | | | <JOIN::exec
| | | | | | >st_select_lex::cleanup()
| | | | | | <st_select_lex::cleanup()
| | | | | <mysql_select/mysql_union
| | | | <handle_select 


延伸阅读:

Tag标签: 查询优化器  
  • 专题推荐

About IT165 - 广告服务 - 隐私声明 - 版权申明 - 免责条款 - 网站地图 - 网友投稿 - 联系方式
本站内容来自于互联网,仅供用于网络技术学习,学习中请遵循相关法律法规