一:Join 的问题?

  - 在实际生产中,使用 join 一般会集中在以下两类:

    - DBA 不让使用 Join ,使用 Join 会有什么问题呢?

    - 如果有两个大小不同的表做 join,应该用哪个表做驱动表呢?

二:数据准备

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

    - 建立 t1,t2 两个完全相同的表,t1 表中写入 100 条数据,t2 表中 写入 1000 条数据。

三:Index Nested-Loop Join(NLJ) (被驱动表有索引的情况选择)

  - 语句

    - 为了避免Mysql选择驱动表对于分析的影响,改用 straight_join 让 MySQL 使用固定的连接方式执行查询。

    - t1 是驱动表,t2 是被驱动表。

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

  - 执行流程

    - 在这条语句里,被驱动表 t2 的字段 a 上有索引,join 过程用上了这个索引

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

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

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

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

    - 

  - 小结

    - 这个过程是先遍历表 t1,然后根据从表 t1 中取出的每行数据中的 a 值,去表 t2 中查找满足条件的记录。

    - 在形式上,这个过程很像写程序时的嵌套查询类似,并且可以用上被驱动表的索引,所以我们称之为“Index Nested-Loop Join”,简称 NLJ。

    - 整个过程, 总扫描行数是 200(t1 200 + t2 索引树200)

四:Block Nested-Loop Join(NLJ)(被驱动表无索引选择)

  - 语句

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

    - 由于表 t2 的字段 b 上没有索引,因此在执行流程时,每次到 t2 去匹配的时候,就要做一次全表扫描。

  - 流程

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

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

    - 

  - 小结

    - 可以看到,在这个过程中,对表 t1 和 t2 都做了一次全表扫描,因此总的扫描行数是 1100。

    - 由于 join_buffer 是以无序数组的方式组织的,因此对表 t2 中的每一行,都要做 100 次判断,总共需要在内存中做的判断次数是:100*1000=10 万次。

    - join_buffer 的大小是由参数 join_buffer_size 设定的,默认值是 256k。如果放不下表 t1 的所有数据话,策略很简单,就是分段放。

五:总结

  - 能不能使用 join ?

    - 如果可以使用 Index Nested-Loop Join 算法,也就是说可以用上被驱动表上的索引,其实是没问题的;

    - 如果使用 Block Nested-Loop Join 算法,扫描行数就会过多。

      - 尤其是在大表上的 join 操作,这样可能要扫描被驱动表很多次,会占用大量的系统资源。所以这种 join 尽量不要用。

  - 如果要使用 join,应该选择大表做驱动表还是选择小表做驱动表?

    - 在决定哪个表做驱动表的时候,应该是两个表按照各自的条件过滤,过滤完成之后,计算参与 join 的各个字段的总数据量,数据量小的那个表,就是“小表”,应该作为驱动表。

《Mysql - 到底可不可以使用 Join ?》的更多相关文章

  1. 简单物联网:外网访问内网路由器下树莓派Flask服务器

    最近做一个小东西,大概过程就是想在教室,宿舍控制实验室的一些设备. 已经在树莓上搭了一个轻量的flask服务器,在实验室的路由器下,任何设备都是可以访问的:但是有一些限制条件,比如我想在宿舍控制我种花 ...

  2. 利用ssh反向代理以及autossh实现从外网连接内网服务器

    前言 最近遇到这样一个问题,我在实验室架设了一台服务器,给师弟或者小伙伴练习Linux用,然后平时在实验室这边直接连接是没有问题的,都是内网嘛.但是回到宿舍问题出来了,使用校园网的童鞋还是能连接上,使 ...

  3. 外网访问内网Docker容器

    外网访问内网Docker容器 本地安装了Docker容器,只能在局域网内访问,怎样从外网也能访问本地Docker容器? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Docker容器 ...

  4. 外网访问内网SpringBoot

    外网访问内网SpringBoot 本地安装了SpringBoot,只能在局域网内访问,怎样从外网也能访问本地SpringBoot? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装Java 1 ...

  5. 外网访问内网Elasticsearch WEB

    外网访问内网Elasticsearch WEB 本地安装了Elasticsearch,只能在局域网内访问其WEB,怎样从外网也能访问本地Elasticsearch? 本文将介绍具体的实现步骤. 1. ...

  6. 怎样从外网访问内网Rails

    外网访问内网Rails 本地安装了Rails,只能在局域网内访问,怎样从外网也能访问本地Rails? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Rails 默认安装的Rails端口 ...

  7. 怎样从外网访问内网Memcached数据库

    外网访问内网Memcached数据库 本地安装了Memcached数据库,只能在局域网内访问,怎样从外网也能访问本地Memcached数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装 ...

  8. 怎样从外网访问内网CouchDB数据库

    外网访问内网CouchDB数据库 本地安装了CouchDB数据库,只能在局域网内访问,怎样从外网也能访问本地CouchDB数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Cou ...

  9. 怎样从外网访问内网DB2数据库

    外网访问内网DB2数据库 本地安装了DB2数据库,只能在局域网内访问,怎样从外网也能访问本地DB2数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动DB2数据库 默认安装的DB2 ...

  10. 怎样从外网访问内网OpenLDAP数据库

    外网访问内网OpenLDAP数据库 本地安装了OpenLDAP数据库,只能在局域网内访问,怎样从外网也能访问本地OpenLDAP数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动 ...

随机推荐

  1. CAS—改动默认登录页

    1.  部署CAS-Server 本文以cas-server-3.4.11-release.zip为例.解压提取cas-server-3.4.11/modules/cas-server-webapp- ...

  2. NSDate 格式化 及 互转

    /* NSDateFormatter的作用 1.NSString -> NSDate 2.NSDate -> NSString */ void fmt_date_to_string(); ...

  3. Android Application Digital Signatures - Android 数字签名

    Android 数字签名 同一个开发人员的多个程序尽可能使用同一个数字证书,这能够带来下面优点. (1)有利于程序升级,当新版程序和旧版程序的数字证书同样时,Android系统才会觉得这两个程序是同一 ...

  4. 数据分析在web交互设计中的作用 页面跳出率 100% 原因分析

    通过分析访问的路径,发现,访问者访问其他页面,直接跳出 页面跳出率  100% 说明: 连作者都发现的导航路径不清晰 对导航进行改版:清晰.明了

  5. Codeforces Round #211 (Div. 2)B. Fence

    B. Fence time limit per test 1 second memory limit per test 256 megabytes input standard input outpu ...

  6. SQL server用到的SQL语句备份下

    这是触发器用于关联条件的 -------------1-------------- set ANSI_NULLS ONset QUOTED_IDENTIFIER ONgo ALTER trigger ...

  7. Fy's dota2

    Fy 觉得自己玩 cf,lol 这种高端游戏已经够厉害了,于 是他决定去玩 dota2.结果 fy 的鼠标右键坏了,所以他就等 到 2250 买了把闪烁匕首,用跳刀前进,准备去送泉水.但 是 fy 一 ...

  8. E20170807-mk

    literal adj. 照字面的; 原义的; 逐字的; 平实的,避免夸张;

  9. js模拟复制

    现在浏览器种类也越来越多,诸如 IE.Firefox.Chrome.Safari等等,因此现在要实现一个js复制内容到剪贴板的小功能就不是一件那么容易的事了.   一.实现点击按钮,复制文本框中的的内 ...

  10. Akka源码分析-Remote-发消息

    上一篇博客我们介绍了remote模式下Actor的创建,其实与local的创建并没有太大区别,一般情况下还是使用LocalActorRef创建了Actor.那么发消息是否意味着也是相同的呢? 既然ac ...