一、前言

最近在写代码的时候,遇到了需要多表连接的一个问题,初始sql类似于:

select * from a left join b on a.x = b.x left join c on c.y = b.y left join d on d.z=c.z

这样的多个left join组合,一方面是心里有点不舒服,总觉得这种写法是有问题的,一方面有有点好奇,直接用inner join会怎样呢?差别在哪里?后续使用inner join发现速度要比left join快一些,所以这边就研究一下这个问题。

二、left join为什么会比 inner join 慢

1、关于逻辑运算量

关于left join的概念,大家是都知道的(返回左边全部记录,右表不满足匹配条件的记录对应行返回null),那么单纯的对比逻辑运算量的话,inner join 是只需要返回两个表的交集部分,left join多返回了一部分左表没有返回的数据。

2、关于mysql连接的算法 Nest Loop Join(嵌套联接循环)

这个算法是mysql默认的连接算法,类似于我们php程序的三个嵌套循环:

(foreach a as v){(foreach b as v1){(foreach c as v2){}}
}

从算法上来看,根据mysql文档,inner join在连接的时候,mysql会自动选择较小的表来作为驱动表,从而达到减少循环次数的目的。我们在使用left join表的时候,默认是使用左表作为驱动表,那么此时左表的大小是我们来控制的,如果控制不当,左表比较大,那么自然循环次数也会变多,效率会下降。

MySQL Nested-Loop Join算法学习

根据这两方面的对比,left join明显被秒成渣,但是我们的实际业务却经常需要使用left join,一切还是要以实际业务为主,所以大家还是仁者见仁智者见智的选择吧。博主这里因为业务并不是很需要left join,所以果断选择使用inner join来连接表。

三、关于 left join的优化

根据上面咱们的对比,基本可以总结出来一些简单的优化方案。

1、left join选择小表作为驱动表(这部分基本是大家的共识)2、如果左表比较大,并且业务要求驱动表必须是左表,那么我们可以通过where条件语句,使得左表被过滤的小一些,主要原理和第一条类似3、关联字段给索引,因为在mysql的嵌套循环算法中,是通过关联字段进行关联,并查询的,所以给关联字段索引很必要4、如果sql里面有排序,请给排序字段加上索引,不然会造成排序使用全表扫描参考:https://www.oschina.net/question/930697_21901725、如果where条件中含有右表的非空条件(除开is null),则left join语句等同于join语句,可直接改写成join语句。 6、根据文档,MySQL能更高效地在声明具有相同类型和尺寸的列上使用索引。所以把表与表之间的关联字段给上encoding和collation(决定字符比较的规则)全部改成统一的类型7、右表的条件列一定要加上索引(主键、唯一索引、前缀索引等),最好能够使type达到range及以上(ref,eq_ref,const,system)

注意: 此处的5、6、7参考博客:https://luxuryzh.iteye.com/blog/1976004 ,这个博客总结的很好,强烈推荐

推荐博客阅读:

MySQL索引原理以及慢查询优化

博主在查过各种资料之后,最终把自己的连接类型改为了inner join,并且给关联字段以及排序字段都加上了索引,速度比起刚开始的时候确实是快了不少。只是说mysql还有很多需要研究的地方,加油吧,碰到并解决,不亏~

end

mysql的left join和inner join的效率对比,以及如何优化相关推荐

  1. php普通索引和唯一索引,mysql下普通索引和唯一索引的效率对比

    昨天有位同事说,他的网页查询过程中发现普通索引和唯一索引的效率是有差别的,普通索引比唯一索引快 今天在我的虚拟机中布置了环境,测试抓图如下: 抓的这几个都是第一次执行的,刷了几次后,取平均值,效率大致 ...

  2. MYSQL学习笔记 (三)JOIN用法

    数据库的操作分开增删改查,其中查询操作基本占系统的90%,大家所说的优化SQL语句基本是优化查询语句.接下来将学习JOIN的用法,JOIN包括:INNER JOIN(内连接).LEFT JOIN(左外 ...

  3. Mysql 优化器内部JOIN算法hash join On-Disk Hash Join Grace Hash Join Hybrid hash join过程详解

    Mysql 各种hash join算法讲解 hash join的概述 提到hash join之前自然得说Nest loop join,以两个表的关联为例,它其实是个双层循环,先遍历外层的表(n条),再 ...

  4. Mysql 优化器内部JOIN算法hash join Nestloopjoin及classic hash join CHJ过程详解

    Mysql hash join之classic hash join CHJ过程详解 hash join的历史 优化器里的hash join算法在SQL Server.Oracle.postgress等 ...

  5. mysql单单写join_MySQL系列之Join大法

    1. Index Nested-Loop Join 概念解释: 假设有t1,t2两张表,在join连接的时候,t1表驱动t2表,t1走的全部扫描,t2表使用了索引, 则这个时候join就使用了&quo ...

  6. mysql join性能_Mysql Join语法解析与性能分析

    一.Join语法概述 join 用于多表中字段之间的联系,语法如下: ... FROM table1 INNER|LEFT|RIGHT JOIN table2 ON conditiona table1 ...

  7. Mysql: 图解 inner join、left join、right join、full outer join、union、union all的区别

    对于SQL的Join,在学习起来可能是比较乱的.我们知道,SQL的Join语法有很多inner的,有outer的,有left的,有时候,对 于Select出来的结果集是什么样子有点不是很清楚.Codi ...

  8. mysql join 与 cross join 效率_浅析Mysql Join语法以及性能优化

    在讲MySQL的Join语法前还是先回顾一下联结的语法,呵呵,其实连我自己都忘得差不多了,那就大家一起温习吧,这里我有个比较简便的记忆方法,内外联结的区别是内联结将去除所有不符合条件的记录,而外联结则 ...

  9. mysql nest loop伪代码_Nested Loop Join

    我们都知道SQL的join关联表的使用方式,但是这次聊的是实现join的算法,join有三种算法,分别是Nested Loop Join,Hash join,Sort Merge Join. MySQ ...

最新文章

  1. UNIX/Linux基本命令大全
  2. adb logcat 抓取日志_App专项测试操作指南-2- 常见的ADB命令(上)
  3. eMMC基础技术8:操作模式1-boot mode
  4. Xamarin截取/删除emoji表情bug解决方案
  5. 16、java包装类
  6. Hdu - 1210 - Eddy's 洗牌问题
  7. Hyper-V 3.0网络虚拟化PART 3:内部交换机
  8. 贺利坚老师汇编课程47笔记:jmp指令无条件转移只修改IP
  9. C++ char,int 之间的相互转换
  10. c#位数不够0补充完_人教版四年级上册数学第六单元《除数是两位数的除法》
  11. centos设置ftp默认端口
  12. 浙江省公务员考试计算机专业,浙江省公务员(机关工作人员)考试计算机专业
  13. Android APP的沉浸式体验
  14. 左手手型投篮姿势教程
  15. 注册表-隐藏快捷图标斜箭头
  16. xmanager 5 linux 6.5,工欲善其事必先利其器 —— Xmanager Enterprise 5 和 RealVNC 5/6 介绍...
  17. redis系列七LUR清除算法
  18. Android 平台下的原生 Markdown 解析器
  19. ubuntu 定时重启/关闭进程
  20. 去掉迅雷导致桌面的右下角不时弹出广告

热门文章

  1. java 整型_Java整型计算
  2. 突然远程连接不上mysql_navicat突然连接不上远程linux服务器上的mysql
  3. torch.stack(), torch.cat()用法详解
  4. Thundernet
  5. makefile 库目录
  6. C++智能指针及其简单实现
  7. eigen跟踪MILTracker
  8. 青龙羊毛——放羊娃(教程)
  9. 七丶青龙nvjdc部署教程+短信验证登录对接傻妞
  10. java自学语法_Java自学笔记(一):基础知识