1.3 简单的小结
函数的输入:
部分执行计划 partial plan
N个剩余表
函数输出:
当 N search_depth,返回search_depth个表的最优执行计划,并合并到部分执行计划
递归调用该函数,输入为:当前部分执行计划 剩余表N-depth
1.4 复杂度分析
join-complex
所以,复杂度可能是O(N*N^search_depth/search_depth)。如果search_depth > N 那么算法的复杂度就是O(N!)。通常MySQL优化器分析的复杂度都是O(N!)。
1.5 边界情形
有两个比较极端的情况:
– 当需要JOIN的表的数量小于search_depth时,这里就退化为一个深度优先的穷举确定最优执行计划
– 当search_depth = 1的时候,函数退化为"极其"贪婪的算法,每次从当前的剩余的表中取一个成本最小的,来扩展当前的执行计划
剩余的情况就是介于上面两者之间。
2. 贪婪的MySQL
在打开了参数prune_level(默认开启)后,MySQL不再使用穷举的方式扩展执行计划,而是在剩余表中直接选取访问最少纪录数的表。按照MySQL手册上的描述是:根据经验来看,这种”educated guess”基本不会漏掉最优的执行计划,但是却可以大大(dramatically )缩小搜索空间。要是你怀疑漏掉了某个最优的执行计划,你可以考虑关闭参数试试,当然这会导致搜索空间增大,优化器执行时间偏长。
这个参数在深度优先搜索中起作用,在进行深度探索时,根据current_record_count和current_read_time,来确定,这是不是一个好的执行计划。(原本是需要递归调用计算成本确定)