紧接着之前的《》中的内容,以下对测试过程进行详细分析。
2.5 LEFT JOIN查询
该测试主要用于测试LEFT JOIN与JOIN的处理逻辑上的差异,具体查询处理逻辑如下所示:
JOIN:prepare阶段
setup_tables():同2.1测试。
setup_fields():同2.1测试。
setup_conds():同2.4测试。
JOIN:optimize阶段
simplify_joins():类似2.4测试。不同之处在于由于LEFT JOIN使用的数据表不能为NULL表,这是由是否有where条件过滤决定的。所以该过程会将LEFT JOIN外链接查询转化为多表联合查询操作,从而忽略LEFT JOIN的链接操作。
optimize_cond():同2.1测试。
make_join_statistics():同2.4测试。
choose_plan():同2.1测试。
greedy_search():同2.1测试。
best_extension_by_limited_search():同2.4测试。
get_best_combination():同2.4测试。
JOIN:exec阶段
以下同2.4测试。
对应的查询计划如下所示:
idselect_typetabletypepossible_keyskeykey_lenrefrowsExtra
1SIMPLEcourseALLPRIMARYNULLNULLNULL20Using Where
1SIMPLEstd_currefPRIMARY,std_cur_ibfk_2std_cur_ibfk_24test.course.cur_id13
1SIMPLEstudenteq_refPRIMARYPRIMARY4test.std_cur.std_id1
通过以上测试发现,除了在simplify_joins()处有略微的不同之外,其他处理逻辑和查询计划与测试2.4都是一样的。而LEFT JOIN从理论来说,会将左边的表的进行全表扫描,而右边的表中如果没有匹配的记录时,会用NULL值填充。然后从查询结果来看,查询的记录并非student表的所有记录。并且从查询计划来看,student表的查询类型不是ALL。
通过查看simplify_joins()函数的注释和源码实现发现,OUTER JOIN可以转化为INNER JOIN,转化的条件与used_tables和not_null_tables的值有关。而not_null_tables的值是根据where条件决定的。如果有where条件过滤,那么LEFT JOIN会被转化为INNER JOIN查询。更进一步的研究,将作为单独的问题进行详细的研究和测试。