先建立两张表,test1和test2,向test1中插入1000条数据,test2中插入100条数据。两张表的表结构相同。
一,执行select * from test2 left join test1 on test1.m = test2.m
第一行语句表示test2表是全表扫描,test1表用到了索引。
这条语句将test2作为驱动表,test1作为被驱动表。遍历test2中表的行,然后到test1中去比对(用到了索引),比对成功的,返回客户端。
二,执行select * from test2 left join test1 on test1.n = test2.n
由于n字段没有索引,explain显示两张表都需要全表扫描。“Using join buffer”的意思是两张表在对比的时候,将数据取到join buffer中,也就是内存中的一块区域,虽然时间复杂度没变,但在内存中比较可以提高速度。
如果explain中看到了"Using join buffer",就说明需要优化join语句了。
如果不用join语句,由业务自己开发,整体流程是:
● 将test2表的数据全部取出select * from test2;
●循环取出的数据,select * from test1 where m = test1.m
可以看到,自己开发在时间复杂度上与使用join差别不大,但流程更清晰。
如果你能对join把握的很好,确实可以使用join,但是如果join的表过多,即使分析explain也很麻烦,也不利于后面的开发维护。
使用join还会引发其他的问题吗?
会。假设我们查询的表是一张非常大的表,而且不经常使用,而我们的join语句又写的不好,就需要对表做多次扫描。mysql在扫描到数据之后,会放进内存中,对于长时间不使用的会淘汰(LRU算法),大量的冷表查询,会导致mysql内存命中率降低,从而影响线上的其他业务,这是生产环境限制使用join的重要原因之一。 还有一个原因就是,如果未来要拆库拆表,再处理join语句就会比较麻烦。
LEFT JOIN是LEFT OUTER JOIN的简写版
内连接(INNER JOIN) :只连接匹配的行
左外连接( LEFT JOIN 或LEFT OUTER JOIN) :包含左边表的全部行(不管右边的表中是否存在与它们匹配的行),以及右边表中全部匹配的行
右外连接( RIGHT JOIN 或RIGHT OUTER JOIN) :包含右边表的全部行(不管左边的表中是否存在与它们匹配的行),以及左边表中全部匹配的行
全外连接( FULL OUTER JOIN ) :包含左、右两个表的全部行,不管另外一边的表中是否存在与它们匹配的行
交叉连接 生成笛卡尔积-它不使用任何匹配或者选取条件,而是直接将一个数据源中的每个行与另一个数据源的每个行都一一匹配( 开发中避免使用 )
内连接inner join的举例说明 :
select * from t_institution i
inner join t_teller t
on i.inst_no = t.inst_no
where i.inst_no = "5801"
其中inner可以省略
等价于早期的连接语法
select * from t_institution i, t_teller t
where i.inst_no = t.inst_no
and i.inst_no = "5801"
左外连接left outer join的举例说明:
select * from t_institution i
left outer join t_teller t
on i.inst_no = t.inst_no
其中outer可以省略
右外连接right outer join的举例说明:
select * from t_institution i
right outer join t_teller t
on i.inst_no = t.inst_no
其中outer可以省略
全外连接full outer join的举例说明:
select * from t_institution i
full outer join t_teller t
on i.inst_no = t.inst_no
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)