MySQL之join
语法
- ... from tb1 join(inner join) tb2 on condition
- ... from tb1 left join tb2 on condition
- ... from tb1 right join tb2 on condition
- ... from tb1 full join tb2 on condition【1】
阿里巴巴Java开发手册
【强制】 超过三个表禁止join。需要join的字段,数据类型必须绝对一致;多表关联查询时,保证被关联的字段需要有索引。
说明 : 即使双表join也要注意表索引、SQL性能。【2】
为什么对join进行限制?join的过程是怎样的?
现在假设有两个表tb1和tb2,都有字段id、a、b,id为主键,a上有索引,tb1中有100行数据,tb2中有1000行数据。【3】
explain ... tb1 join tb2 on tb1.a = tb2.a
会发现tb1是全表扫描,tb2是走的索引,这很好理解相当于两层for,只是第二层可以通过所以找到想找的值。具体过程为依次从tb1中读一行,再去通过索引找tb2中满足条件的行。explain ... tb1 join tb2 on tb1.a = tb2.b
因为没有索引,这就是两层for了,显然时间复杂度是不可接受的,因此MySQL的做法是这样:- 将tb1放到join_buffer中(当然这里也可能出现放不下的情况)
- 全表扫描tb2,然后与join_buffer中的数据进行比较找到满足条件的行(这个专栏其实没有讨论tb2放不下的情况,待补充)。这里举个例子说明一下为什么可以加快速度,假设tb1需要分5次才能放到join_buffer中,对于其中的一次来说,将tb1的1/5放入到join_buffer中,再对tb2全表扫描,接着对比tb1和tb2找到满足条件的行,而这样的操作需要5次才能完成,也就是说tb2有5次的全表扫描,若采用类似于两层for的方式的话需要:5 * join_buffer中的大小(前提是第5次也正好满了),不过就是tb1的行数。因此两种方式对于tb2的全表扫描的次数对比为:tb1需要分的次数 vs tb1的行数,差距是非常大的。
由此可知如果被驱动表condition的字段没有索引的话,会有很大的开销,因此如果在数据量较大的情况下一定要要确保被驱动表中加上索引。
如何优化join?
...
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端