作者:阿伟~

链接:https://www.cnblogs.com/sy270321/p/12760211.html

准备我们需要的表结构和数据

两张表 studnet(学生)表和score(成绩)表, 创建表的SQL语句如下

CREATE TABLE `student` (

`id` int(11) NOT NULL,

`no` varchar(20) DEFAULT NULL,

`name` varchar(20) DEFAULT NULL,

PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE `score` (

`id` int(11) NOT NULL,

`no` varchar(20) DEFAULT NULL,

`chinese` double(4,0) DEFAULT NULL,

`math` double(4,0) DEFAULT NULL,

`engilsh` double(4,0) DEFAULT NULL,

PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

MySQL连接查询分为以下三种

left join 左连接,用法如下,这种查询会把左表(student)所有数据查询出来,右表不存在的用空表示,结果图如下

select * from student s1 left join score  s2 on  s1.on = s2. on

right join 右连接, 用法如下,这种查询会把右表(score)所有数据查询出来,左表不存在的用空表示,结果图如下

select * from student s1 right join score s2 on s1.no = s2.no

inner join 内连接,用法如下,这种查询会把左右表都存在的数据查询出来,不存在数据忽略,结果图如下

select * from student s1 inner join score s2 on s1.no = s2.no

连接查询中需要注意的点

什么是驱动表,什么是被驱动表,这两个概念在查询中有时容易让人搞混,有下面几种情况,大家需要了解。

当连接查询没有where条件时,左连接查询时,前面的表是驱动表,后面的表是被驱动表,右连接查询时相反,内连接查询时,哪张表的数据较少,哪张表就是驱动表

当连接查询有where条件时,带where条件的表是驱动表,否则是被驱动表

怎么确定我们上面的两种情况呢,执行计划是不会骗人的,我们针对上面情况分别看看执行计划给出的答案

首先第一种情况,student表中3条数据,score表中2条数据,但两张表中只有一条数据是关联的(编号是1),看如下SQL查询

//左连接查询

explain select * from student s1 left join score s2 on s1.no = s2.no

//右连接查询

explain select * from student s1 right join score s2 on s1.no = s2.no

//内连接查询

explain select * from student s1 inner join score s2 on s1.no = s2.no

执行计划中靠前的表是驱动表,我们看下面三种图中,是不是全度符合情况一,第一张图中s1是驱动表,第二张图中s2是驱动表,第三种途中s2是驱动表

其次第二种情况,还是上面三种SQL语句,我们分别加上where条件,再来看看执行计划的结果是什么样呢?

//左连接查询

explain select * from student s1 left join score s2 on s1.no = s2.no

where s2. no = 1

//右连接查询

explain select * from student s1 right join score s2 on s1.no = s2.no

where s1.no = 1

//内连接查询

explain select * from student s1 inner join score s2 on s1.no = s2.no

where s1.no = 1

我们看下面三种执行计划结果,全都以where条件为准了,而且跟上面情况一的都相反了,因此情况二也是得到了验证.

连接查询优化

要理解连接查询优化,得先理解连接查询的算法,连接查询常用的一共有两种算法,我们简要说明一下

Simple Nested-Loop Join Algorithms (简单嵌套循环连接算法)

比如上面的查询中,我们确定了驱动表和被驱动表,那么查询过程如下,很简单,就是双重循环,从驱动表中循环获取每一行数据,再在被驱动表匹配满足条件的行。

for (row1 : 驱动表) {

for (row2 : 被驱动表){

if (conidtion == true){

send client

}

}

}

Index Nested-Loop Join Algorithms (索引嵌套循环连接算法)

上面双重for循环的查询中,相信很多研发人员看到这种情况第一个想法就是性能问题,是的,join查询的优化思路就是小表驱动大表,而且在大表上创建索引(也就是被动表创建索引),如果驱动表创建了索引,MySQL是不会使用的

for (row1 : 驱动表) {

索引在被驱动表中命中,不用再遍历被驱动表了

}

Block Nested-Loop Join Algorithm(基于块的连接嵌套循环算法)

其实很简单就是把一行变成了一批,块嵌套循环(BNL)嵌套算法使用对在外部循环中读取的行进行缓冲,以减少必须读取内部循环中的表的次数。例如,如果将10行读入缓冲区并将缓冲区传递到下一个内部循环,则可以将内部循环中读取的每一行与缓冲区中的所有10行进行比较。这将内部表必须读取的次数减少了一个数量级。

MySQL连接缓冲区大小通过这个参数控制 : join_buffer_size

MySQL连接缓冲区有一些特征,只有无法使用索引时才会使用连接缓冲区;联接中只有感兴趣的列存储在其联接缓冲区中,而不是整个行;为每个可以缓冲的连接分配一个缓冲区,因此可以使用多个连接缓冲区来处理给定查询;在执行连接之前分配连接缓冲区,并在查询完成后释放连接缓冲区

所以查询时最好不要把 * 作为查询的字段,而是需要什么字段查询什么字段,这样缓冲区能够缓冲足够多的行。

从上面的执行计划中其实我们已经看到了 useing join buffer了,是的,那是因为我们对两张表都有创建索引

三种算法优先级

第一种算法忽略,MySQL不会采用这种的,当我们对被驱动表创建了索引,那么MySQL一定使用的第二种算法,当我们没有创建索引或者对驱动表创建了索引,那么MySQL一定使用第三种算法

怎样知道mysql的驱动是什么_MySQL连接查询到底什么是驱动表?看了这里你应该就明白了...相关推荐

  1. 小白终是踏上了这条不归路----小文的mysql学习笔记(6)----连接查询-----等值连接、非等值连接、自链接、外连接、交叉连接

    ** 小白终是踏上了这条不归路----小文的mysql学习笔记(1) 小白终是踏上了这条不归路----小文的mysql学习笔记(2)----条件查询 小白终是踏上了这条不归路----小文的mysql学 ...

  2. Mysql进阶学习(五)连接查询(包含sql92标准和sql99标准)

    Mysql进阶学习(五)连接查询(包含sql92标准和sql99标准) 一.进阶6:连接查询 (一).sql92标准 1.等值连接 1.1 等值连接简介 案例1:查询女神名和对应的男神名 案例2:查询 ...

  3. MySQL获取连接_MySQL 连接查询超全详解

    1 作用 在MySQL中join操作被称为连接,作用是能连接多个表的数据(通过连接条件),从多个表中获取数据合并在一起作为结果集返回给客户端.例如: 表A: id name age 1 A 18 2 ...

  4. mysql查询动态表名的数据类型_Mysql中查询某个数据库中所有表的字段信息

    前言 有时候,需要在数据库中查询一些字段的具体信息,而这些字段又存在于不同的表中,那么我们如何来查询呢? 在每一个数据库链接的information_schema数据库中,存在这样一张表--COLUM ...

  5. mysql显示表的所有列车_MySQL中查看当前数据库的所有表

    关键词 MySQL数据库 表 摘要 本文介绍在MySQL数据库中,如何列出并查看当前数据库的所有表. 本文介绍在MySQL数据库中,如何列出并查看当前数据库的所有表. 我们创建一个数据库之后,数据库里 ...

  6. mysql外连接的含义_MySQL连接查询,内连接,外连接,全连接,交叉连接_cly_32的博客-CSDN博客...

    原文作者:起个花名好难 原文标题:MySQL连接查询,内连接,外连接,全连接,交叉连接 发布时间:2021-01-27 13:46:33 1.含义 当查询中涉及到多个表的字段,需要使用多表查询 sel ...

  7. mysql数据库计算全部女生_mysql数据库基础操作大全(小白必看)

    一.概念: 数据: data 数据库: DB 数据库管理系统:DBMS 数据库系统:DBS MySQL:数据库 mysql:客户端命令(用来连接服务或发送sql指令) SQL:结构化查询语言 ,其中M ...

  8. mysql查找并删除记录_mysql 子查询删除记录

    mysql 子查询删除记录 mysql 可以通过子查询得到要删除的记录条件,然后通过子查询得结果匹配要删除的记录.但是 mysql 不能直接删除子查询表中的数据,必须通过一个临时表来解决.例如: de ...

  9. mysql的右连接查询_mysql连接查询(左连接,右连接,内连接)

    一.mysql常用连接 INNER JOIN(内连接,或等值连接):获取两个表中字段匹配关系的记录. LEFT JOIN(左连接):获取左表所有记录,即使右表没有对应匹配的记录. RIGHT JOIN ...

最新文章

  1. wamp(ajax)
  2. python 短进程优先算法_黄哥Python:图深度优先算法(dfs)
  3. CTR模型越来越深,如何让它变轻?
  4. Java .Net Byte数组存储差异以及解决方法
  5. 图片优化之下一代图片格式WebP和AVIF
  6. oracle父游标和子游标,诊断Oracle high version count(高版本游标)问题
  7. 每日编程-20170326
  8. 详解linux netstat输出的网络连接状态信息
  9. IOS为UIImageView图片添加点击事件
  10. 使用“Apple 诊断”来测试您的Mac 是不是存在硬件问题
  11. 基于CompactRIO的嵌入式车载电性能测试系统研发
  12. java 地心坐标系(ECEF)和WGS-84坐标系(WGS84)互转
  13. mac iphone模拟器 真机 操作
  14. java 反射基础_Java反射的基本使
  15. python字符串行列转换_Excel、SQL、Python分别实现行列转换
  16. Spark列级血缘(字段级别血缘)开发与实现
  17. 微信小程序开发学习5(自定义组件)
  18. 轻松完美-实现ECharts双Y轴左右刻度线一致
  19. 完全用Linux:半年来,Linux高效完成我所有的工作!(转贴)
  20. HttpRequest 和HttpWebRequest的区别(转)

热门文章

  1. VC编译DLL时,如何不依赖VC运行库
  2. 计算机算法——进入计算机世界
  3. python案例教程钱毅湘_Python案例教程 清华大学出版社 钱毅湘等 高等学校通识教育系列教材 软件工具 程序设计Python...
  4. Java拆分为姓和名
  5. 灾难恢复_有效的灾难恢复计划的10个技巧
  6. 默认google浏览器打不开链接(点击超链接没有反应)
  7. 美国知名科技博客简介
  8. 一个列子演示java中软引用的回收时机
  9. 秘密分享(Secret Sharing)
  10. 【Person Re-ID】AlignedReID: Surpassing Human-Level Performance in Person Re-Identification