一: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. MySQL hash分区(四)

    具体描写叙述总结请看MySQL分区(一) 样例:该样例为本人个人学习总结分享->具体说明-->有问题欢迎前来交流 watermark/2/text/aHR0cDovL2Jsb2cuY3Nk ...

  2. springmvc20170322

    <?xml version="1.0" encoding="UTF-8"?> <web-app version="3.0" ...

  3. [NOIP2003普及组]麦森数(快速幂+高精度)

    [NOIP2003普及组]麦森数(快速幂+高精度) Description 形如2^P-1的素数称为麦森数,这时P一定也是个素数.但反过来不一定,即如果P是个素数,2^P-1不一定也是素数.到1998 ...

  4. 面向对象软件工程与UML

    软件工程基本概念 软件危机 软件的功能.规模及复杂性与日俱增,软件的复杂性达到了它的开发者难以控制的程度 这种情况导致了严重的后果: 软件可靠性下降 开发效率低下 维护极为困难 这使软件开发者陷入困境 ...

  5. Filter,Interceptor和Aspect

    过滤器使用的主要是反射 :拦截器使用的主要是回调 :AOP使用的主要是动态代理. 一个请求过来 ,先进行过滤器处理,看程序是否受理该请求.过滤器放过后, 程序中的拦截器进行处理,处理完后进入被AOP动 ...

  6. PCB 规则引擎之JSON对象查看器

    在PCB规则引擎开发中,JavaScript V8引擎是处理业务逻辑的, 当然业务逻辑需要数据支撑才行,  即需有将数据推进入到V8引擎.目前这边数据传输到JavaScript V8引擎以C# Mod ...

  7. spring基础学习---简单配置文件

  8. webpack的初步使用(01)

    webpack:1.安装:在项目文件下先npm init初始化,一路回车2.进入到建立的项目下:cd projectname3.安装webpack:npm install webpack --save ...

  9. discuz的cutstr函数

    function cutstr($string, $length, $dot = ' ...') { if(strlen($string) <= $length) { return $strin ...

  10. Kafka详解与总结(一)

    1. Kafka概述 1.1. 消息队列 1)点对点模式(一对一,消费者主动拉取数据,消息收到后消息清除) 点对点模型通常是一个基于拉取或者轮询的消息传送模型,这种模型从队列中请求信息,而不是将消息推 ...