为什么代码规范要求SQL语句不要过多的join?
首选先阐述一下SQL join的用法以及对应结果集
inner join 内连接
- 将两个表中的关联条件相同的结果取出
left join 左连接
- 将两个表中的关联条件相同的结果以及左表(主表)的全部数据取出,若对应不上关联条件则给NULL
right join 右连接
- 将两个表中的关联条件相同的结果以及右表(主表)的全部数据取出,若对应不上关联条件则给NULL
full join 全连接
- 将两个表中的所有数据取出
那么在实际开发中避免不了使用join,那么优化jon有什么方法
分两种情况:
- 数据规模小的 > 直接塞到内存中
- 数据规模大的 > 可以通过增加索引来优化join语句的执行速度,可以通过冗余信息来减少join的次数,尽量减少表连接的次数,一个SQL语句表连接的次数不要超过5次
对于SQL语句来说join还是比较耗费性能的
这就要说一下join的执行过程
SQL在执行join语句的时候必然要有一个比较的过程
逐条比较两个表的语句是比较慢的,因此我们可以把两个表中数据依次读进一个内存块中, 以MySQL的InnoDB引擎为例,使用以下语句我们必然可以查到相关的内存区域show variables like '%buffer%
如图所示join_buffer_size的大小将会影响我们join语句的执行性能
具体原因:
join_buffer_size:应用程序经常会出现一些两表(或多表)Join的操作需求,MySQL在完成某些 Join 需求的时候(all/index join),为了减少参与Join的“被驱动表”的读取次数以提高性能,需要使用到 Join Buffer 来协助完成 Join操作。当 Join Buffer 太小,MySQL 不会将该 Buffer 存入磁盘文件,而是先将Join Buffer中的结果集与需要 Join 的表进行 Join 操作,然后清空 Join Buffer 中的数据,继续将剩余的结果集写入此 Buffer 中,如此往复。这势必会造成被驱动表需要被多次读取,成倍增加 IO 访问,降低效率。
在一大前提下,任何项目终究要上线,不可避免的要产生数据,数据的规模又不可能太小
所以大部分数据库中的数据最终要保存到硬盘上,并且以文件的形式进行存储。
以MySQL的InnoDB引擎为例
- InnoDB以页(page)为基本的IO单位,每个页的大小为16KB
- InnoDB会为每个表创建用于存储数据的.ibd文件
验证:
这意味着我们有多少表要连接就需要读多少个文件,虽然可以利用索引,但还是免不了频繁的移动硬盘的磁头,也就是说频繁的移动磁头会影响性能。