MySQL使用join的正确姿势

使用join的正确姿势:

  1. 使用 join 语句,性能比强行拆成多个单表执行 SQL 语句的性能要好;

  2. 如果使用 join 语句的话,需要让小表做驱动表。

如果不能使用被驱动表的索引的话,查询效率很低,慎用。比如两张表t1和t2各100行。如果不使用索引,MySQL需要扫描100*100共10000行;而使用索引的情况下,t1全表扫描100行;t2扫描100次,每次扫描1行,共扫描200行。

什么是驱动表

MySQL先从哪个表检索,这个表就是驱动表

join语句涉及MySQL中的三种算法

分别是NLJ(Nested-Loop Join)、Simple Nested-Loop Join、Block Nested-Loop Join(BNL)。

  • NLJ: 在能够使用被驱动表索引的情况下,MySQL会选择NLJ算法。

  • BNL:当无法使用驱动表的索引,MySQL会把表一次性或分段加载到join buffer中,然后再与被驱动表中的数据匹配。这就是BNL算法。

  • Simple Nested-Loop Join: 他的执行逻辑与BNL很相似,但是Simple Nested-Loop Join不会把表数据加载到join buffer中,而是buffer pool中,这会间接对MySQL性能产生很大的影响。

Example

有两个表t1和t2,

CREATE TABLE `t2` (
 `id` int(11) NOT NULL,
 `a` int(11) DEFAULT NULL,
 `b` int(11) DEFAULT NULL,
 PRIMARY KEY (`id`),
 KEY `a` (`a`)
) ENGINE=InnoDB;

下面的join语句的一般执行流程是:

  • select * from t1 straight_join t2 on (t1.a=t2.a);

(NLJ)

  1. 从表 t1 中读入一行数据 R;

  2. 从数据行 R 中,取出 a 字段到表 t2 里去查找;

  3. 取出表 t2 中满足条件的行,跟 R 组成一行,作为结果集的一部分;

  4. 重复执行步骤 1 到 3,直到表 t1 的末尾循环结束。

  • select * from t1 straight_join t2 on (t1.a=t2.b);

(BLJ)

把表 t1 的数据读入线程内存 join_buffer 中,由于我们这个语句中写的是 select *,因此是把整个表 t1 放入了内存;

  1. select * from t1 straight_join t2 on (t1.a=t2.b);

  2. 扫描表 t2,把表 t2 中的每一行取出来,跟 join_buffer 中的数据做对比,满足 join 条件的,作为结果集的一部分返回。

即将发布的文章

  • 大公司为什么不让使用join

关注公众号,回复“MySQL”领取高清PDF《高性能MySQL》

 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值