你知道 Sql 中 left join 的底层原理吗?

2019-09-10阅读 7130
https://cloud.tencent.com/developer/column/2367
 

01.前言

写过或者学过 Sql 的人应该都知道 left join,知道 left join 的实现的效果,就是保留左表的全部信息,然后把右表往左表上拼接,如果拼不上就是 null。除了 left join以外,还有inner join、outer join、right join,这些不同的 join 能达到的什么样的效果,大家应该都了解了,如果不了解的可以看看网上的帖子或者随便一本 Sql 书都有讲的。今天我们不讲这些 join 能达到什么效果,我们主要讲这些 join 的底层原理是怎么实现的,也就是具体的效果是怎么呈现出来的。

为什么要讲底层原理呢?因为只有懂底层原理了,才知道如何更好的去写 join 语句,最后才能提高 select 的查询速度。

join 主要有Nested Loop、Hash Join、Merge Join这三种方式,我们这里只讲最普遍的,也是最好的理解的Nested Loop,Nested Loop 翻译过来就是嵌套循环的意思,那什么又是嵌套循环呢?嵌套大家应该都能理解,就是一层套一层;那循环呢,你可以理解成是 for 循环。

Nested Loop 里面又有三种细分的连接方式,分别是Simple Nested-Loop Join、Index Nested-Loop Join、Block Nested-Loop Join,接下来我们就分别去看一下这三种细分的连接方式。

在正式开始之前,先介绍两个概念,驱动表(也叫外表)和被驱动表(也叫非驱动表,还可以叫匹配表,亦可叫内表),简单来说,驱动表就是主表,left join 中的左表就是驱动表,right join 中的右表是驱动表。一个是驱动表,那另一个就只能是非驱动表了,在 join 的过程中,其实就是从驱动表里面依次(注意理解这里面的依次)取出每一个值,然后去非驱动表里面进行匹配,那具体是怎么匹配的呢?这就是我们接下来讲的这三种连接方式。

02.Simple Nested-Loop Join

Simple Nested-Loop Join 是这三种方法里面最简单,最好理解,也是最符合大家认知的一种连接方式,现在有两张表table A 和 table B,我们让 table A left join table B,如果是用第一种连接方式去实现的话,会是怎么去匹配的呢?直接上图:

上面的 left join 会从驱动表 table A 中依次取出每一个值,然后去非驱动表 table B 中从上往下依次匹配,然后把匹配到的值进行返回,最后把所有返回值进行合并,这样我们就查找到了table A left join table B的结果。是不是和你的认知是一样的呢?利用这种方法,如果 table A 有10行,table B 有10行,总共需要执行10 x 10 = 100次查询。

这种暴力匹配的方式在数据库中一般不使用。

03.Index Nested-Loop Join

Index Nested-Loop Join 这种方法中,我们看到了 Index,大家应该都知道这个就是索引的意思,这个 Index 是要求非驱动表上要有索引,有了索引以后可以减少匹配次数,匹配次数减少了就可以提高查询的效率了。

为什么会有了索引以后可以减少查询的次数呢?这个其实就涉及到数据结构里面的一些知识了,给大家举个例子就清楚了。

上图中左边就是普通列的存储方式,右边是树结构索引,什么是树结构呢?就是数据分布的像树这样一层一层的,树结构有一个特点就是左边的数据小于顶点的数,右边的数大于顶点的数,你看右图中,左边的数3是不是小于顶点6,右边的数7是不是大于顶点6;左边的数1是不是小于顶点3,右边的数4是不是大于顶点3。

假如我们现在要匹配数值9,如果是左边这种数据存储方式的话,我们需要从第一行依次匹配到最后一行才能找到数值9,总共需要匹配7次;但是如果我们是用右边这种树结构索引的话,我们先拿9和最上层顶点6去匹配,发现9比6大,我们就去顶点的右边去找,再去和7匹配,发现9仍然比7大,再去7的右边找,就找到了9,这样我们只匹配了3次就把我们想要的9找到了。是不是相比匹配7次节省了很多时间。

数据库中的索引一般用 B+ 树,为了让大家更好的理解,我上面画的图只是最简单的一种树结构,而非真实的 B+ 树,但是原理是一样的。感兴趣的同学可以去看我写的数据结构的文章:

如果索引是主键的话,效率会更高,因为主键必须是唯一的,所以如果被驱动表是用主键去连接,只会出现多对一或者一对一的情况,而不会出现多对多和一对多的情况。

04.Block Nested-Loop Join

理想情况下,用索引匹配是最高效的一种方式,但是在现实工作中,并不是所有的列都是索引列,这个时候就需要用到 Block Nested-Loop Join 方法了,这种方法与第一种方法比较类似,唯一的区别就是会把驱动表中 left join 涉及到的所有列(不止是用来on的列,还有select部分的列)先取出来放到一个缓存区域,然后再去和非驱动表进行匹配,这种方法和第一种方法相比所需要的匹配次数是一样的,差别就在于驱动表的列数不同,也就是数据量的多少不同。所以虽然匹配次数没有减少,但是总体的查询性能还是有提升的。

mysql join 底层原理的更多相关文章

  1. MySql join匹配原理

    疑问 表:sl_sales_bill_head 订单抬头表 数据行:8474 表:sl_sales_bill          订单明细 数据行:8839 字段:SALES_BILL_NO 订单号 情 ...

  2. mysql join优化原理

    http://blog.itpub.net/22664653/viewspace-1692317/ http://itindex.net/detail/46772-%E4%BC%98%E5%8C%96 ...

  3. 深入理解 MySQL 索引底层原理

    https://mp.weixin.qq.com/s/qHJiTjpvDikFcdl9SRL97Q

  4. java架构之路-(mysql底层原理)Mysql之让我们再深撸一次mysql

    让我再深撸一次mysql吧,这次主要以应对面试来说说mysql,大概几个方向,索引结构,查询引擎,索引优化,explain的详解和trace工具的使用. 索引: 我们先来看一下mysql的B+tree ...

  5. MySQL数据库索引的底层原理(二叉树、平衡二叉树、B-Tree、B+Tree)

    1.MySQL数据库索引的底层原理 https://mp.weixin.qq.com/s/zA9KvCkkte2mTWTcDv7hUg

  6. SQL中 left join 的底层原理

    介绍 left join的实现效果就是保留左表的全部信息,将右表往左表上拼接,如果拼不上则为NULL. 除了left join以外,还有inner join.outer join.right join ...

  7. MySQL JOIN原理

    先看一下实验的两张表: 表comments,总行数28856 表comments_for,总行数57,comments_id是有索引的,ID列为主键. 以上两张表是我们测试的基础,然后看一下索引,co ...

  8. java架构之路-(mysql底层原理)Mysql事务隔离与MVCC

    上几篇博客我们大致讲了一下mysql的底层结构,什么B+tree,什么Hash需要回行啊,再就是讲了mysql优化的explain,这次我们来说说mysql的锁. mysql锁 锁从性能上分为乐观锁( ...

  9. MySQL JOIN原理(转)

    先看一下实验的两张表: 表comments,总行数28856 表comments_for,总行数57,comments_id是有索引的,ID列为主键. 以上两张表是我们测试的基础,然后看一下索引,co ...

随机推荐

  1. Aluminum: An Asynchronous, GPU-Aware Communication Library Optimized for Large-Scale Training of Deep Neural Networks on HPC Systems

    本文发表在MLHPC 2018上,主要介绍了一个名为Aluminum通信库,这个库针对Allreduce做了一些关于计算通信重叠以及针对延迟的优化,以加速分布式深度学习训练过程. 分布式训练的通信需求 ...

  2. JUC之Java中的阻塞队列及其实现原理

    在文章线程池实现原理 - 池塘里洗澡的鸭子 - 博客园 (cnblogs.com)中介绍了线程池的组成部分,其中一个组成部分就是阻塞队列.那么JAVA中的阻塞队列如何实现的呢? 阻塞队列,关键字是阻塞 ...

  3. Oracle表数据或结构误删还原

    数据误删 表结构没有发生改变 --开启表字段转移,不开启无法还原 alter table 表名 enable row movement; --数据闪回 flashback table 表名 to ti ...

  4. 【基础篇】js对本地文件增删改查--增

    前置条件: 1. 本地有安装node,点击传送门 项目目录: 1. msg.json内容 { "data": [ { "id": 1, "name&q ...

  5. 【测试必备】k8s基本使用(更新中。。。)

    测试为什么要学习容器技术及k8s k8s不是运维的专属技术 随着互联网技术的发展,架构也已经从单体架构发展到容器云( "微服务 + k8s" 完美结合) 很多人认为,k8s只是运维 ...

  6. 商业智能bi行业现状,BI应用的3个层次

    ​商业智能bi行业现状.传统的报表系统技术上已经相当成熟,大家熟悉的Excel等都已经被广泛使用.但是,随着数据的增多,需求的提高,传统报表系统面临的挑战也越来越多. 1. 数据太多,信息太少 密密麻 ...

  7. 数据分析用这样的报表工具,秒杀Excel!

    报表工具是为满足公司对报表数据的业务需求,弥补第三方报表平台给项目开发定制报表的工作而自主研发的一个通用性强易于维护的web报表工具. 报表工具以NPOI基础架构,通过公司的REAP开发框架运用到所有 ...

  8. 数据分析刚入门?这几个BI软件你一定得知道!

    在当前乃至未来5年的职场中,将取代你的可能不是 AI ,而是比你"更懂"数据分析的同事.毕竟,现在做什么都讲究"用数字说话",很多岗位在招聘JD中均给出了&qu ...

  9. Smartbi代替Alteryx+Tableau,用1份投入如何获得2份回报?

    Smartbi是国内一家知名的BI厂商,Alteryx.Tableau是国外两款重要的BI工具,它们都是在BI领域内提供特定的功能,以满足企业的数据分析需求.那么,对于用户来说,在选择BI工具的时候要 ...

  10. 转载 CoreCLR源码探索(七) JIT的工作原理(入门篇)

    转载自:https://www.cnblogs.com/zkweb/p/7687737.html 很多C#的初学者都会有这么一个疑问, .Net程序代码是如何被机器加载执行的? 最简单的解答是, C# ...