MySQL中的 inner join 和 left join的区别解析(小结果集驱动大结果集)

 更新时间:2023年05月06日 10:51:57   作者:@大吉  
这篇文章主要介绍了MySQL中的 inner join 和 left join的区别解析,本文通过场景描述给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

场景描述

以一个场景为例:

单据A:下游子表 (数据量级小)
单据B:下游主表(数据量级小)
单据C:中游子表(数据量级小)
单据D:中游主表(数据量级小)
单据E:上游子表(数据量级小)
单据F:上游主表(比其他表数据量级大)

需求:将单据F的某个字段,刷到单据A的某个字段上面。从A到F,都可以通过id连接索引的形式,来关联。但是A到F的连接顺序必须是从A到F顺序连接。比如:

这几个表的连接可以用下面的例子演示:

a join b on a.id = b.id
b join c on b.id = c.mainId
c join d on c.id = d.tableId
d join e on d.id = e.tid
e join f on e.tid = f.code

inner join 和 left join 的区别

我们写update语句的时候,肯定是想要用join连表的。但是到底是使用inner join;还是left join比较好呢?

  • left join:

select a.*,b.* from a left join b on a.id = b.id , 这两个表连接,根据后面的on条件,如果b表里面的b.id不符合 a.id = b.id ,那么a表里面的所有数据列都会给展示出来。然后b表没有这种数据,所以sql里面的 b.* 会被全部填充成null

  • inner join:

select a.*,b.* from a inner join b on a.id = b.id , 这两个表连接,根据后面on条件,如果b表里面的b.id不符合 a.id = b.id ,那么a表里面的部分数据列(不符合a.id = b.id条件的)就不会展示。

根据上面的定义,left join常用于select 语句;这是为了防止a表会少一些匹配记录,为了能展示全a表,所以使用left join。

如下图所示:

索引角度理解小结果集驱动大结果集

不管是 left join 和 inner join,都要注意小结果集驱动大结果集。a表 join b表的时候,

还是看之前例子的SQL:

select a.*,b.* from a left join b on a.id = b.id

假设a表数量级是100万条,b表数量级是100条。我这样连接,就是大表驱动小表;直接看查找次数:

在用后面on条件连接两个表的时候,首先要走B+树索引进行匹配;拿a表这100w的数量级,逐条对比 -> B+树 -> 匹配到 b表的记录。假设B+树查找b表的100条要用2次查找,那么最终查找次数就是: 100万 * 2 次

如果是小表驱动大表:

select a.*,b.* from b left join a on a.id = b.id

那么就会拿b表这100条,逐条对比 -> B+树 -> 匹配到 a表的记录。假设B+树查找a表的100w条要用3次查找,那么最终查找次数就是: 100 * 3 次

从索引匹配的角度讲,小结果集驱动大结果集的效率优化了不是一点半点。我们要有意识地让小表在左边,大表在右边

但是如果你用的是inner join,MySQL内部会做优化,自动让小表在前大表在后。也就是说你怎么写,效率都是一样的。但是left join却不能自动优化,这点需要注意!

update语句常用 inner join而不是left join

举例如下SQL:

(任务目标:用f 表字段更新a表字段)

update a 
inner join b on a.id = b.id
inner join c on b.id = c.mainId
inner join d on c.id = d.tableId
inner join e on d.id = e.tid
inner join f on e.tid = f.code
set a.Demand_orgid = f.req_org_id
where xxx = xxx;

update 原则上 都得用inner join。

看上面的SQL,假设你全部都用的left join做关联,由于你最终update 的是 a的字段;假设a表在left join的过程中,因为某个点匹配不到f表,那么用f 表字段更新a表字段 这一个过程中,一旦有任意一个环节匹配不到,那么f 表的字段全都会用null填充。最终,a表匹配不到f表的数据,都会被更新成null !

但是如果你用inner join,用f 表字段更新a表字段 这一个过程中,一旦有任意一个环节匹配不到,那么a表匹配不到 f 表的所有数据就不会显示,也就是说不会更新。

你想想,你都匹配不到数据列。你还更新啥,难道更新null吗。基于上面的原因,inner join 其实就满足需求了

况且!left join 要考虑这几张表的大小关系,谁大谁小,小结果集驱动大结果集。但是inner join 就完全不用考虑此问题,因为inner join MySQL内部会做优化,自动让小表在前大表在后。

到此这篇关于MySQL中的 inner join 和 left join的区别的文章就介绍到这了,更多相关mysql inner join 和 left join区别内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 监控MySQL主从状态的shell脚本

    监控MySQL主从状态的shell脚本

    这篇文章主要分享了监控MySQL主从状态的shell脚本,帮助大家更好的监控mysql数据库,保持稳定性,感兴趣的朋友可以了解下
    2020-12-12
  • MySQL5.0存储过程教程

    MySQL5.0存储过程教程

    Introduction 简介 MySQL 5.0 新特性教程是为需要了解5.0版本新特性的MySQL老用户而写的。简单的来说是介绍了“存储过程、触发器、视图、信息架构视图”,在此感谢译者陈朋奕的努力.
    2008-04-04
  • mysql 设置默认的时间值

    mysql 设置默认的时间值

    由于MySQL目前字段的默认值不支持函数
    2009-05-05
  • MySql安装步骤图文教程及中文乱码的解决方案

    MySql安装步骤图文教程及中文乱码的解决方案

    这篇文章主要介绍了MySql安装步骤图文教程及中文乱码的解决方案,非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2016-08-08
  • MySQL数据库高级数据操作之新增数据

    MySQL数据库高级数据操作之新增数据

    这篇文章主要介绍了MySQL数据库高级数据操作之新增数据,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-06-06
  • MySQL新手入门进阶语句汇总

    MySQL新手入门进阶语句汇总

    这篇文章主要给大家介绍了关于MySQL新手入门进阶语句的相关资料,总结分析了MySQL数据库常用的查询、条件查询、排序、连接查询、子查询等相关操作技巧,文中通过图文介绍的非常详细,需要的朋友可以参考下
    2022-09-09
  • MySQL InnoDB row_id边界溢出验证的方法步骤

    MySQL InnoDB row_id边界溢出验证的方法步骤

    这篇文章主要给大家介绍了关于MySQL InnoDB row_id边界溢出验证的方法步骤,文中通过示例代码介绍的非常详细,对大家的学习或者使用MySQL InnoDB具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-10-10
  • mysql root密码的重设方法(亲测可用)

    mysql root密码的重设方法(亲测可用)

    这篇文章主要介绍了如何重设mysql root密码,需要的朋友可以参考下
    2014-02-02
  • MSSQL产生死锁的根本原因及解决方法

    MSSQL产生死锁的根本原因及解决方法

    死锁是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去.此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等的进程称为死锁进程
    2016-04-04
  • MySQL中使用表别名与字段别名的基本教程

    MySQL中使用表别名与字段别名的基本教程

    这篇文章主要介绍了MySQL中使用表别名与字段别名的基本教程,利用SELECT语句和AS子句进行取别名的操作,需要的朋友可以参考下
    2015-12-12

最新评论