浅谈 MySQL 连表查询

连表查询是一把双刃剑, 优点是适应范式, 减少数据冗余; 缺点是连表查询特别是多张表的连表会增加数据库的负担, 降低查询效率.

简介

连表查询就是 2 张表或者多张表的联合查询, 联合查询的结果称之为 "笛卡尔积", 假设 A 表中有 n 条记录, B 表中有 m 条记录, "笛卡尔积" 就是 n*m

各种连表查询的本质就是对笛卡尔积的过滤

  • 全查询: 全量查询笛卡尔积, n*m 种结果, 不加关键字过滤
  • 内连接: 关键字是 INNER JOIN, JOIN, WHERE, 或者自然匹配(省略连表条件, 不建议使用!!!)
  • 外连接:
    • 左外连接: 关键字是 LEFT JOIN, LEFT OUTER JOIN
    • 右外连接: 关键字是 RIGHT JOIN, RIGHT OUTER JOIN

这里有一张神图

数据准备

  1. create table `user_a` (
  2. `aid` int(11) NOT NULL AUTO_INCREMENT,
  3. `a_name` varchar(255) NOT NULL,
  4. `age` smallint NOT NULL,
  5. PRIMARY KEY(`aid`)
  6. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT '测试表A';
  7. create table `user_b` (
  8. `bid` int(11) NOT NULL AUTO_INCREMENT,
  9. `b_name` varchar(255) NOT NULL,
  10. `age` smallint NOT NULL,
  11. PRIMARY KEY(`bid`)
  12. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT '测试表B';
  13. # 插入测试数据
  14. INSERT INTO `user_a`(aid, a_name, age) VALUES(1, 'test1', 1),(2, 'test2', 2),(3, 'test3', 3);
  15. INSERT INTO `user_b`(bid, b_name, age) VALUES(1, 'test2', 2),(2, 'test3', 3),(4, 'test4', 4);

全查询

  1. # 全查询: 下面的结果都是等价的
  2. # [推荐] INNER JOIN
  3. SELECT * FROM user_a INNER JOIN user_b;
  4. SELECT * FROM user_a, user_b;
  5. SELECT * FROM user_a JOIN user_b;
  6. SELECT * FROM user_a CROSS JOIN user_b;

结果: 全量查询 n*m 种可能性

内连接

对 n*m 的笛卡尔积进行过滤, 用 WHERE 或者 ON 关键字都是等价的(内连接是等价的, 外连接不是等价的)

(建议使用 ON 关键字, 约定俗称)

  1. # 内连接: 下面的结果都是等价的
  2. # [推荐] INNER JOIN + ON
  3. SELECT * FROM user_a a INNER JOIN user_b b ON a.a_name=b.b_name;
  4. # INNER JOIN + WHERE
  5. SELECT * FROM user_a a JOIN user_b b ON a.a_name=b.b_name;
  6. # JOIN + ON
  7. SELECT * FROM user_a a JOIN user_b b ON a.a_name=b.b_name;
  8. # JOIN + WHERE
  9. SELECT * FROM user_a a JOIN user_b b WHERE a.a_name=b.b_name;
  10. # 多表 + WHERE
  11. SELECT * FROM user_a a, user_b b WHERE a.a_name=b.b_name;

结果: 只有左边和右边同时存在才会返回再结果集里面

外连接

外连接包括左连接和右连接

左连接

  1. # 左连接
  2. # [唯一写法] LEFT JOIN + ON
  3. SELECT * FROM user_a a LEFT JOIN user_b b ON a.a_name=b.b_name;

结果: 保证左边的数据完整, 如果右边没有该数据, 则右边的数据为 NULL

右连接

  1. # 右连接
  2. # [唯一写法] RIGHT JOIN + ON
  3. SELECT * FROM user_a a RIGHT JOIN user_b b ON a.a_name=b.b_name;

结果: 保证右边的数据完整, 如果左边没有该数据, 则左边的数据为 NULL

ON 和 WHERE 的区别

ON 和 WHERE 在内连表的时候是没有区别的 (推荐使用 INNER JOIN + ON 的规范写法)

外连接只能用 ON, 外连接用 WHERE 直接语法错误

为什么要小表驱动大表

因为连接查询的本质是遍历左边表的记录去匹配右边表的记录, 左边表的复杂度是 O(n), 右边表能走索引 O(log n)

总结

  • 全量查询: 推荐使用 INNER JOIN 查询整个笛卡尔集, 不常用
  • 内连接: 推荐使用 INNER JOIN + ON
  • 左连接: 推荐使用 LEFT JOIN + ON
  • 右连接: 推荐使用 RIGHT JOIN + ON
  • 使用小表驱动大表, 因为驱动表的复杂度是 O(n), 被驱动表的复杂度是 O(log n)

reference

https://juejin.cn/post/7043811976270577672

本文由mdnice多平台发布

浅谈 MySQL 连表查询的更多相关文章

  1. 浅谈MySQL分表

    关于分表:顾名思义就是一张数据量很大的表拆分成几个表分别进行存储. 我们先来大概了解以下一个数据库执行SQL的过程: 接收到SQL --> 放入SQL执行队列 --> 使用分析器分解SQL ...

  2. 浅谈MySQL多表操作

    字段操作 create table tf1( id int primary key auto_increment, x int, y int ); # 修改 alter table tf1 modif ...

  3. 浅谈MySQL中优化sql语句查询常用的30种方法 - 转载

    浅谈MySQL中优化sql语句查询常用的30种方法 1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中使 ...

  4. 浅谈mysql innodb缓存策略

    浅谈mysql innodb缓存策略: The InnoDB Buffer Pool Innodb 持有一个存储区域叫做buffer pool是为了在内存中缓存数据和索引,知道innodb buffe ...

  5. 浅谈mysql配置优化和sql语句优化【转】

    做优化,我在这里引用淘宝系统分析师蒋江伟的一句话:只有勇于承担,才能让人有勇气,有承担自己的错误的勇气.有承担错误的勇气,就有去做事得勇气.无论做什么事,只要是对的,就要去做,勇敢去做.出了错误,承担 ...

  6. 浅谈Mysql共享锁、排他锁、悲观锁、乐观锁及其使用场景

    浅谈Mysql共享锁.排他锁.悲观锁.乐观锁及其使用场景   Mysql共享锁.排他锁.悲观锁.乐观锁及其使用场景 一.相关名词 |--表级锁(锁定整个表) |--页级锁(锁定一页) |--行级锁(锁 ...

  7. MySQL多表查询之外键、表连接、子查询、索引

    MySQL多表查询之外键.表连接.子查询.索引 一.外键: 1.什么是外键 2.外键语法 3.外键的条件 4.添加外键 5.删除外键 1.什么是外键: 主键:是唯一标识一条记录,不能有重复的,不允许为 ...

  8. 浅谈mysql主从复制的高可用解决方案

    1.熟悉几个组件(部分摘自网络)1.1.drbd     —— DRBD(Distributed Replicated Block Device),DRBD号称是 "网络 RAID" ...

  9. Mysql 单表查询 子查询 关联查询

    数据准备: ## 学院表create table department( d_id int primary key auto_increment, d_name varchar(20) not nul ...

  10. (转)Mysql 多表查询详解

    MySQL 多表查询详解 一.前言  二.示例 三.注意事项 一.前言  上篇讲到mysql中关键字执行的顺序,只涉及了一张表:实际应用大部分情况下,查询语句都会涉及到多张表格 : 1.1 多表连接有 ...

随机推荐

  1. 最好的在线PDF转换工具服务

    工作中有时候会碰到需要转换PDF文件的情况,现在网上就要很多免费的在线工具,可以进行PDF文件的转换,下面就来介绍一些可以直接在浏览器中将文档.电子表格.和图片转换为PDF或者互相转换的服务工具. ​ ...

  2. RTOS入门

    RTOS是什么? RTOS是一款操作系统,相当于Windows\Linux 分为ucos FreeRTOS RT-Thread LiteOS 比裸机开发的优势在于,多任务系统,不必串行 临界区 临界区 ...

  3. 如何实现sm3加密

    SM3加密应用 何为sm3加密? SM3是由中国国家密码管理局设计的一种密码杂凑函数,类似于SHA-256和MD5等国际标准的散列算法.SM3算法是中国国家标准<GB/T 32905-2016 ...

  4. Mesh快连

    Mesh快连 一.名词解释 Mesh快连是一种由多个节点组成的网络系统,这些节点可以相互连接,形成一个"网状"的结构. 二.如何使用 有线Mesh: 网络拓扑: 设备版本:3.7. ...

  5. jquery中封装了三种ajax请求方式

          // jQuery中封装了3种 ajax 请求方式         // 1, get请求方式         // 2, post请求方式         // 3, 综合请求方式    ...

  6. CF题解合集

    CF 比赛题解合集 目录 CF 比赛题解合集 1952 A. Ntarsis' Set B. Imbalanced Arrays C. Ina of the Mountain D. Miriany a ...

  7. [SWPUCTF 2021 新生赛]gift_F12

    首先我们打开环境会发现花里胡哨的,而题目中有提示:F12,所以我们直接F12查看源码 然后ctrl+f信息检索flag.直接找到flag提交 但要注意提交格式为NSSCTF{}

  8. 前端使用 Konva 实现可视化设计器(14)- 折线 - 最优路径应用【代码篇】

    话接上回<前端使用 Konva 实现可视化设计器(13)- 折线 - 最优路径应用[思路篇]>,这一章继续说说相关的代码如何构思的,如何一步步构建数据模型可供 AStar 算法进行路径规划 ...

  9. docker容器单机编排

    随着网站架构的升级,容器也使用的越发频繁,应用服务和容器间的关系也越发复杂. 这就要求研发人员能够更好的方法去管理数量较多的容器服务,而不能手动的去挨个管理. 例如一个LNMP的架构,就得部署web服 ...

  10. Spring AOP 中@Pointcut的用法(多个Pointcut)

    Spring AOP 中@Pointcut的用法(多个Pointcut) /** swagger切面,分开来写 **/ @Aspect @Component public class ApiOpera ...