2023-05-15 mysql-join-思考

文章探讨了MySQL数据库中的JOIN操作,从磁盘IO、集合论和过滤条件的角度分析了内外连接的差异。强调了外连接保持表序的重要性以及在特定情况下将外连接转换为内连接的优化方法。还提到了nestedloop、blocknestedloop和hashjoin等算法,并指出索引在查询优化中的关键作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

摘要:

记录mysql数据库里对于join的思考

思考:

  1. 从磁盘IO角度,复杂度可以分为一趟算法和两趟算法, 至于多趟算法则被简化为两趟算法的合成
  2. 从集合论的角度,可以分为外连接和内连接, 也就是left/right join和inner join
  3. 外连接不能改变表的顺序, 但是内连接可以. 外连接改变表的顺序将破坏语义
  4. 如果确定外连接查询的数据不存在null, 那么采用空值拒绝策略, 可以将外连接转换为内连接, 有助于后续优化. 可以参考函数 simpy_join
  5. 从filter的角度, 过滤条件可以分为在join过程中和在join结束后, 也就是说谓词出现在on和出现在where, 是涉及的过滤的时机不一样
  6. 即使是多表的join, 在mysql中也是会以两表join进行展开运算
  7. 应该将小表放在前边, 作为驱动表. 
    1. 直观上是认为驱动表都在内存中, 所以小表作为驱动表, 但是实际情况要涉及到代价计算
    2. 假设两表数据量是n和m, 那么无论谁做驱动表, 都必须完成n+m次的磁盘io加载数据, 但是驱动表是需要额外存放在内存中, 那么小表作为驱动表, 磁盘io数量最少
  8. 最简单粗暴和广为人知的join策略是nested loop, 可以理解成两层for循环, 驱动表在外层, 被驱动表在内层
  9. mysql查询优化器的核心就是索引, 只有当没有索引的情况,才开始做nested loop
  10. 对nested loop的改进有block nestd loop, 采用批量物化
  11. 到了mysql8.0, nested loop的一个重大改进是hash join
  12. 对于外连接, 条件出现在on和where有本质的不同, 涉及语义的变化
  13. 对于内连接, 条件出现在on和where的执行结构是等价的
    1. 从而尽量的利用空值拒绝等特点将外连接转换成内连接
    2. 方便对条件进行下推和上推
  14. 内连接可以不带on条件, 此时内连接的结果为两表的笛卡尔积
  15. 外连接必须带on条件
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

悟世者

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值