MySQL查询优化器源码分析--整体流程

来源:互联网 发布:淘宝店铺转让靠谱吗 编辑:程序博客网 时间:2024/05/29 13:09

函数间关系的主要逻辑如下:

handle_select(){――第(1)层

  mysql_union(); //处理union操作

  mysql_select(){――第(2)层

JOIN::optimize() {――第(3)层

  simplify_joins(); //把外连接简化为内连接 

optimize_cond(…,conds, …); //优化whrer子句

optimize_cond(…,having, …); //优化having子句

opt_sum_query();//优化count(*), min()and max(),只适用于没有group子句的情况

make_join_statistics();//确定多表的连接路径;单表是多表的特例

{――第(4)层

  update_ref_and_keys();//获取索引信息,为快速定位数据、条件比较做准备

    get_quick_record_count();//估算每个表中有多少元组可用(被循环调用计算多个表,包括了范围查询的代价计算
choose_plan()//做最优的多表连接以便得到最优的查询计划
    {――第(5)层
      //挑选三种多表连接的方式之一做最优的多表连接以便得到最优的查询计划
      optimize_straight_join(); //方式一:用户指定表的连接次序
      find_best (); //方式二:MySQL早期的多表连接次序算法
      greedy_search(); //方式三:MySQL新的多表连接次序算法
      {――第(6)层
        best_extension_by_limited_search()
        {――第(7)层
          best_access_path()//估算局部查询树的最佳访问路径
        }
      }//――第(6)层结束

}//――第(5)层结束

  }//――第(4)层结束

……

make_outerjoin_info();//填充外连接的信息

……

substitute_for_best_equal_field();//循环遍历所有表达式,化简表达式(重复的等式能去掉则直接去掉,如:WHERE a=5 AND ((a=b AND b=c) OR  c>4) 的条件将变为:“=(a) and (=(5abc)or c>4)”)[1]

……

make_join_select(); //用于执行各种不同情况的join查询。该函数通过join时,连接表的不同搜索方式(唯一索引查找、ref查找、快速范围查找、合并索引查找、全表扫描等不同方式),进行join操作的处理

 

//优化distinct谓词相关的情况,如下多行代码,处理不同的distinct情况

……

 

//创建临时表

//处理简单的IN子查询

}――第(3)层结束,optimize()

}――第(2)层结束,mysql_select()

}――第(1)层结束,handle_select()

以上是查询优化的整体流程,在进入第4层之前是的逻辑查询计划生成,如外连接转换为內连接、表达式化简、子查询的消除等逻辑优化策略都是在这个阶段之前完成的。

 

4层之后是物理查询计划生成,利用贪婪(greddy)算法,实现多个关系的访问方式确定(顺序访问、索引访问)、连接方式确定(嵌套循环连接算法)、连接顺序选取。



[1] 如执行如下sql,并查看其查询计划,可以看到查询计划的条件发生了变化:

create table t(a int, b int, c int, dint);

insert into t values(1,2,3,4);

insert into t values(5,5,5,5);

insert into t values(10,20,30,40);

explain EXTENDED select * from tWHERE a=5 AND ((a=b AND b=c) OR  c>4);

SHOW WARNINGS;

查询计划的结果为:

select `test`.`t`.`a` AS`a`,`test`.`t`.`b` AS `b`,`test`.`t`.`c` AS `c`,`test`.`t`.`d` AS `d` from`test`.`t` where ((`test`.`t`.`a` =5) and (((`test`.`t`.`b` = 5) and (`test`.`t`.`c` = 5)) or (`test`.`t`.`c` >4)))

0 0
原创粉丝点击