共计 991 个字符,预计需要花费 3 分钟才能阅读完成。
1.前言
近日,线上小伙伴反映某接口响应时间长,笔者跟踪后优化了查询,追加了联合索引。但是万万没想到,线上和开发环境的执行计划居然有所不同,这就勾起了笔者的兴趣。
2.谁在搞鬼
众所周知,Mysql会自动优化sql,但是通常不会有太大出入。笔者发现Mysql的 join optimizer也犯了糊涂,原本的小表驱动大表居然没有处理,执行计划表明它首先处理的大表,估算了1万多行数据,最终过滤了91%的数据行,与此同时,与之关联的小表只有一行满足条件的数据。。。简直离谱!这时候就需要手动干预 join optimizer进程了。Mysql关联查询定义
[info]joined_table: { table_reference {[INNER | CROSS] JOIN | STRAIGHT_JOIN} table_factor [join_specification] | table_reference {LEFT|RIGHT} [OUTER] JOIN table_reference join_specification | table_reference NATURAL [INNER | {LEFT|RIGHT} [OUTER]] JOIN table_factor }[/info]
STRAIGHT_JOIN登场,STRAIGHT_JOIN和JOIN很像,但是它有一个特点,那就是左边的表永远比右边的表先读取,意味着join optimizer将不会优化左右表的读取顺序。在某些情况下避免关联表错误的被join optimizer调整读取顺序,最终影响查询效率。假如说查询如下
SELECT t1.name, t2.salary FROM employee t1 INNER JOIN info t2 ON t1.name = t2.name;
join optimizer优化后可能成了这样
SELECT t1.name, t2.salary FROM info t2 INNER JOIN employee t1 ON t1.name = t2.name;
那么等价的忽略join optimizer优化
SELECT t1.name, t2.salary FROM employee t1 STRAIGHT_JOIN info t2 ON t1.name = t2.name;
3.小结
本文简单描述了如何在特定场景下取消join optimizer优化,STRAIGHT_JOIN值得拥有!当然切忌不可滥用!