前言:

多表联合查询,其实就是我们MySQL中的join语句,经常会看到有人说join非常影响性能,不建议使用,你知道这是为什么呢?我们究竟可不可以用呢?

测试数据:

CREATE TABLE `t2` (
`id` int(11) NOT NULL,
`a` int(11) DEFAULT NULL,
`b` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `a` (`a`)
) ENGINE=InnoDB; drop procedure idata;
delimiter ;;
create procedure idata()
begin
declare i int;
set i=1;
while(i<=1000)do
insert into t2 values(i, i, i);
set i=i+1;
end while;
end;;
delimiter ;
call idata(); create table t1 like t2;
insert into t1 (select * from t2 where id<=100)
上述SQL创建了2个表,两张表都有主键索引id,普通索引a。存储过程是往表t2里插入1000行数据,在表t1里插入的是100行数据。
如果直接使用join语句,优化器可能会选择表t1或者表t2作为驱动表,这样会影响分析SQL执行过程。所以为了分析执行过程中的性能问题,我们可以使用straight_join让MySQL使用固定的连接方式查询,下述语句就是让t1作为驱动表,t2作为被驱动表。
select * from t1 straight_join t2 on (t1.a =t2.a);
我们通过explain来看一下这条语句的执行结果。
这里可以看出,在这条语句汇总,被驱动表t2字段a上有索引,join过程用上了这个索引,该语句的执行流程如下;
  1. 从表t1中读取一行数据R
  2. 从数据行R中,取出a字段到表t2里去查找
  3. 取出表t2中满足条件的行,跟R组成一行,作为结果集的一部分
  4. 重复执行步骤1到3,直到表t1的末尾循环结束。
上述的过程和我们写程序时的循环查找类似,并且可以使用被驱动表中的索引
在这个流程里,对驱动表t1做了全表扫描,这个过程扫描了1000行数据。由于被驱动表使用了索引,我们构造的数据都是11对应的,所以每次只扫描1行数据,总扫描也是100行,扫描总行数为200

如果不使用join会怎样呢?

如果不使用join,那么我们需要将t1的数据全部取出,然后取出a的值,记为$R.a在执行select * from t2 where a= $R.a,再讲结果和R构成结果集的一行。
这样做虽然也是扫描了100行数据,但是总共执行了101条语句,与MySQL服务器多了100次交互,而且还需要自己去构建结果集。这么做显然没有直接join要好。

Simple-Nested-Loop join

在上述SQL执行的过程中,驱动表走的是全表扫描,被驱动表走的是数搜索,所以整个过程的时间复杂度可以近似表示为:O(n*log2m),所以我们应该尽量使用小表来做驱动表
当n扩大1000倍的时候,时间复杂度扩大1000倍,m扩大1000倍的时候,这个数值只扩大10不到10倍。
结论:
  1. 使用join语句,性能比强拆成多个单表执行SQL语句的性能要好
  2. 如果使用join语句的话,需要让小表做驱动表
当然,这个结论是建立在“可以使用被驱动表的索引”的前提下的。

Block Nested-Loop Join:

这个时候,按照我们上面的分析,会不会取笛卡尔积,扫描100*1000次呢?我们可以使用explain来查看一下下面的SQL执行结果:
select * from t1 straight_join t2 on (t1.a=t2.b);
 
可以看到这里采用了一种Block Nested-Loop Join的算法。
具体的运算流程是这样的:
  1. 把表t1的数据读入到线程内存join_buffer中,由于我们这个语句中写的是select * 因此会讲整个表t1放入内存。
  2. 扫描表t2,把t2中的每一行数据取出来,跟join_buffer中的数据做对比,满足join条件的,作为结果集的一部分返回。
我们可以看到,该算法的计算次数是:100*1000=10万次。但是Block Nested-Loop Join虽然在时间复杂度上和Simple-Nested-Loop join算法一致,但是由于是内存计算,所以速度上会快很多,性能也更好。
这里还是应该选择小表作为驱动表,因为如果驱动表太大,那么就需要将驱动表分段载入内存,将驱动表分成多少段,那么就需要扫描被驱动表多少次。所以这里还是推荐使用小表作为的驱动表。

结论:

如果可以使用被驱动表的索引,join语句非常有优势
不能使用被驱动表的索引,只能使用Block Nested-Loop Join算法,尽量不要使用
在使用join的时候,应选择小表作为驱动表

你了解MySQL中的多表联合查询吗?的更多相关文章

  1. Mysql中实现多表关联查询更新操作

    今天一下要记录一下才行了,每次都要去网上查找方法,每次都难找得要命 Mysql在更新某些字段的数据时,有时候会依据其他表的数据进行更新,需要通过关联后对不同的行更新不同的值,传统的update set ...

  2. MYSQL中只知表名查询属于哪个SCHEMA

    只知道表名XXX查该表属于哪个schema.以及该表有哪些列等信息 SELECT * from information_schema.columns WHERE table_name = 'xxx'; ...

  3. 【mysql】mysql中单列索引、联合索引、Join联表查询建立索引 和 EXPLAIN的分析使用

    2.创建联合索引,从坐到右分别为:userid.openId.name   2. #### --------------  多表联合查询 update 2019/03/13  ------------ ...

  4. 理解mysql执行多表联合查询

    阅读目录 一:inner join(内连接) 二:left join(左连接) 三:right join(右连接) 四:cross join(交叉连接) 五:union操作 六:node+mysql ...

  5. mysql中的回表查询与索引覆盖

    了解一下MySQL中的回表查询与索引覆盖. 回表查询 要说回表查询,先要从InnoDB的索引实现说起.InnoDB有两大类索引,一类是聚集索引(Clustered Index),一类是普通索引(Sec ...

  6. mysql中把一个表的数据批量导入另一个表中

    mysql中把一个表的数据批量导入另一个表中   不管是在网站开发还是在应用程序开发中,我们经常会碰到需要将MySQL或MS SQLServer某个表的数据批量导入到另一个表的情况,甚至有时还需要指定 ...

  7. 数据库MySQL中关于“多表关联更新”的那些事

    在常见的sql中,我们经常在查询中进行多表关联查询,用的比较熟练.今天在开发中遇到一个实际业务场景是多表关联更新,一时不知所措.本着多学习的态度,没有直接写java代码去实现,终于把多表关联更新的sq ...

  8. 七十七、SAP中数据库操作之多表联合查询

    一.我们看一下SFLIGHT表和SPFLI表,表结构如下 二.这2个表的数据如下 三.我们代码如下 四.多表联合查询结果如下

  9. mybatis:开发环境搭建--增删改查--多表联合查询(多对一)

    什么是mybatisMyBatis是支持普通SQL查询,存储过程和高级映射的优秀持久层框架.MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索.MyBatis使用简单的XML或 ...

随机推荐

  1. hihoCode 1075 : 开锁魔法III

    时间限制:6000ms 单点时限:1000ms 内存限制:256MB 描述 一日,崔克茜来到小马镇表演魔法. 其中有一个节目是开锁咒:舞台上有 n 个盒子,每个盒子中有一把钥匙,对于每个盒子而言有且仅 ...

  2. C#通过对象属性名修改值

    摘自:csdn 给一个对象属性赋值可以通过PropertyInfo.SetValue()方式进行赋值,但要注意值的类型要与属性保持一致.    创建对象实例的两种方法: 1. var obj = As ...

  3. 我们一起学Python之——认识Python"规则"

    前言: 开学后,跟预想的一样,开学第一天我们就开了Python,虽然之前早就预料到了,但对于一直学Java的我来说,内心还是有一些涟漪的.总归还是要接受的,还不如振作起来,认真对待.我决定从最简单并且 ...

  4. web前端Vue+Django rest framework 框架 生鲜电商项目实战视频教程 ☝☝☝

    web前端Vue+Django rest framework 框架 生鲜电商项目实战视频教程    web前端Vue+Django rest framework 框架 生鲜电商项目实战视频教程 学习 ...

  5. 全面系统Python3入门+进阶课程 ✌✌

    全面系统Python3入门+进阶课程 (一个人学习或许会很枯燥,但是寻找更多志同道合的朋友一起,学习将会变得更加有意义✌✌) 无论是大数据.人工智能还是机器学习,Python都是最热门的首选语言 ,这 ...

  6. App自动化之坐标定位

    1.如下图定位"去看看"这个按钮的坐标,可以看到右侧bonds属性:[374,831][654,906] 2.点右上角"搜索"按钮,查看bonds属性:[615 ...

  7. 自学web前端达到什么水平,才能满足求职的标准?

    大多数野生程序员最棘手的问题就是如何依靠技术解决温饱,通俗来讲就是技术折现的问题. 如果是单纯出于兴趣,或者只是为了突击某一阶段或者某一项目技术壁垒,不跟就业挂钩的自学倒也是无关痛痒.但是当上岗成为自 ...

  8. js转换页面为图片并下载

    <div style="background:red;width: 600px;height: 600px;" class="test"> < ...

  9. mongodb学习笔记系列一

    一.简介和安装 ./bin/mongod --dbpath /path/to/database --logpath /path/to/log --fork --port 27017 mongodb非常 ...

  10. travis-ci + php + casperjs 持续集成

    .travis.yml 文件添加内容: sudo: required language: php php: - 5.5 before_script: - npm install -g casperjs ...