为什么代码规范要求SQL语句不要过多的join?

来源:juejin.im/post/5e0443ae6fb9a0162277a2c3

1.Linux如何查看内存的使用情况?

free 或者 top

2.free命令可以看到那些信息?

  • total 总内存
  • used 已用内存
  • fres 空闲内存
  • buff/cache 已使用的缓存
  • avaiable 可用内存

3.如何清理已使用的缓存(buff/cache)?

sync; echo 3 > /proc/sys/vm/drop_caches

再谈SQL join
1.SQL join理解?

SQL中的join可以根据某些条件把指定的表给结合起来并将数据返回给客户端

join的方式有
inner join 内连接
为什么代码规范要求SQL语句不要过多的join?
left join 左连接
为什么代码规范要求SQL语句不要过多的join?
right join 右连接
为什么代码规范要求SQL语句不要过多的join?
full join 全连接
为什么代码规范要求SQL语句不要过多的join?
如果需要使用join语句,如何优化提升性能?

  • 可以通过增加索引来优化join语句的执行速度
  • 可以通过冗余信息来减少join次数
  • 尽量减少表连接的次数,一个SQL语句表连接的次数不要超过5次

为什么join语句相对耗费性能?

1.在执行join语句时候必然有个比较过程,逐条比较两个表的语句是较慢的,因此我们可以把两个表中的数据依此读进一个内存块,以MySQL的InnoDB引擎为例,使用以下语句可以查到相关的内存区域
show variables like ‘%buffer%’
为什么代码规范要求SQL语句不要过多的join?
大部分数据库中的数据最终要保存到硬盘上,并且以文件的形式进行存储。
以MySQL的InnoDB引擎为例

  • InnoDB以页(page)为基本的IO单位,每个页的大小为16KB
  • InnoDB会为每个表创建用于存储数据的.ibd文件
    为什么代码规范要求SQL语句不要过多的join?
    为什么代码规范要求SQL语句不要过多的join?
    这意味着我们有多少表要连接就需要读多少个文件,虽然可以利用索引,但还是避免不了频繁的移动硬盘的磁头

《CSAPP》(深入理解计算机系统)里面说过一句话
存储器层次结构的本质是,每一层存储设备都是较低一层设备的缓存
为什么代码规范要求SQL语句不要过多的join?
通俗的来说,就是Linux会把内存当作是硬盘的高速缓存

Join算法
无索引的处理方式

Nested Loop Join
为什么代码规范要求SQL语句不要过多的join?
嵌套循环,每次只读取表中的一行数据,也就是说如何outerTable有10万行数据,innerTable有100行数据,需要读取1000万次(假设这俩个表的文件没有被操作系统缓存到内存,我们称之为冷数据表)
缺陷:速度慢,不建议使用
Block nested loop
为什么代码规范要求SQL语句不要过多的join?
Block块,也就是说每次都会取一块数据到内存以减少I/O的开销
无索引使用时MySQL InnoDB会使用这种算法;