浅谈 MySQL 连表查询
浅谈 MySQL 连表查询
连表查询是一把双刃剑, 优点是适应范式, 减少数据冗余; 缺点是连表查询特别是多张表的连表会增加数据库的负担, 降低查询效率.
简介
连表查询就是 2 张表或者多张表的联合查询, 联合查询的结果称之为 "笛卡尔积", 假设 A 表中有 n 条记录, B 表中有 m 条记录, "笛卡尔积" 就是 n*m
各种连表查询的本质就是对笛卡尔积的过滤
- 全查询: 全量查询笛卡尔积,
n*m种结果, 不加关键字过滤 - 内连接: 关键字是 INNER JOIN, JOIN, WHERE, 或者自然匹配(省略连表条件, 不建议使用!!!)
- 外连接:
- 左外连接: 关键字是 LEFT JOIN, LEFT OUTER JOIN
- 右外连接: 关键字是 RIGHT JOIN, RIGHT OUTER JOIN
这里有一张神图

数据准备
create table `user_a` (
`aid` int(11) NOT NULL AUTO_INCREMENT,
`a_name` varchar(255) NOT NULL,
`age` smallint NOT NULL,
PRIMARY KEY(`aid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT '测试表A';
create table `user_b` (
`bid` int(11) NOT NULL AUTO_INCREMENT,
`b_name` varchar(255) NOT NULL,
`age` smallint NOT NULL,
PRIMARY KEY(`bid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT '测试表B';
# 插入测试数据
INSERT INTO `user_a`(aid, a_name, age) VALUES(1, 'test1', 1),(2, 'test2', 2),(3, 'test3', 3);
INSERT INTO `user_b`(bid, b_name, age) VALUES(1, 'test2', 2),(2, 'test3', 3),(4, 'test4', 4);
全查询

# 全查询: 下面的结果都是等价的
# [推荐] INNER JOIN
SELECT * FROM user_a INNER JOIN user_b;
SELECT * FROM user_a, user_b;
SELECT * FROM user_a JOIN user_b;
SELECT * FROM user_a CROSS JOIN user_b;
结果: 全量查询 n*m 种可能性

内连接

对 n*m 的笛卡尔积进行过滤, 用 WHERE 或者 ON 关键字都是等价的(内连接是等价的, 外连接不是等价的)
(建议使用 ON 关键字, 约定俗称)
# 内连接: 下面的结果都是等价的
# [推荐] INNER JOIN + ON
SELECT * FROM user_a a INNER JOIN user_b b ON a.a_name=b.b_name;
# INNER JOIN + WHERE
SELECT * FROM user_a a JOIN user_b b ON a.a_name=b.b_name;
# JOIN + ON
SELECT * FROM user_a a JOIN user_b b ON a.a_name=b.b_name;
# JOIN + WHERE
SELECT * FROM user_a a JOIN user_b b WHERE a.a_name=b.b_name;
# 多表 + WHERE
SELECT * FROM user_a a, user_b b WHERE a.a_name=b.b_name;
结果: 只有左边和右边同时存在才会返回再结果集里面

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

# 左连接
# [唯一写法] LEFT JOIN + ON
SELECT * FROM user_a a LEFT JOIN user_b b ON a.a_name=b.b_name;
结果: 保证左边的数据完整, 如果右边没有该数据, 则右边的数据为 NULL

右连接

# 右连接
# [唯一写法] RIGHT JOIN + ON
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 连表查询的更多相关文章
- 浅谈MySQL分表
关于分表:顾名思义就是一张数据量很大的表拆分成几个表分别进行存储. 我们先来大概了解以下一个数据库执行SQL的过程: 接收到SQL --> 放入SQL执行队列 --> 使用分析器分解SQL ...
- 浅谈MySQL多表操作
字段操作 create table tf1( id int primary key auto_increment, x int, y int ); # 修改 alter table tf1 modif ...
- 浅谈MySQL中优化sql语句查询常用的30种方法 - 转载
浅谈MySQL中优化sql语句查询常用的30种方法 1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中使 ...
- 浅谈mysql innodb缓存策略
浅谈mysql innodb缓存策略: The InnoDB Buffer Pool Innodb 持有一个存储区域叫做buffer pool是为了在内存中缓存数据和索引,知道innodb buffe ...
- 浅谈mysql配置优化和sql语句优化【转】
做优化,我在这里引用淘宝系统分析师蒋江伟的一句话:只有勇于承担,才能让人有勇气,有承担自己的错误的勇气.有承担错误的勇气,就有去做事得勇气.无论做什么事,只要是对的,就要去做,勇敢去做.出了错误,承担 ...
- 浅谈Mysql共享锁、排他锁、悲观锁、乐观锁及其使用场景
浅谈Mysql共享锁.排他锁.悲观锁.乐观锁及其使用场景 Mysql共享锁.排他锁.悲观锁.乐观锁及其使用场景 一.相关名词 |--表级锁(锁定整个表) |--页级锁(锁定一页) |--行级锁(锁 ...
- MySQL多表查询之外键、表连接、子查询、索引
MySQL多表查询之外键.表连接.子查询.索引 一.外键: 1.什么是外键 2.外键语法 3.外键的条件 4.添加外键 5.删除外键 1.什么是外键: 主键:是唯一标识一条记录,不能有重复的,不允许为 ...
- 浅谈mysql主从复制的高可用解决方案
1.熟悉几个组件(部分摘自网络)1.1.drbd —— DRBD(Distributed Replicated Block Device),DRBD号称是 "网络 RAID" ...
- Mysql 单表查询 子查询 关联查询
数据准备: ## 学院表create table department( d_id int primary key auto_increment, d_name varchar(20) not nul ...
- (转)Mysql 多表查询详解
MySQL 多表查询详解 一.前言 二.示例 三.注意事项 一.前言 上篇讲到mysql中关键字执行的顺序,只涉及了一张表:实际应用大部分情况下,查询语句都会涉及到多张表格 : 1.1 多表连接有 ...
随机推荐
- Linux权限与组
rwx r-xr r-x root root r:读 (read) 4 w:写(write) 2 x:执行(execute) ``1 - 没有权限 0 权限 的前三位 rwx 属主权限位(用户权限) ...
- [机器学习] 低代码机器学习工具PyCaret库使用指北
PyCaret是一个开源.低代码Python机器学习库,能够自动化机器学习工作流程.它是一个端到端的机器学习和模型管理工具,极大地加快了实验周期,提高了工作效率.PyCaret本质上是围绕几个机器学习 ...
- 使用jasypt对springboot配置信息加密
1.pom文件增加依赖 <dependency> <groupId>com.github.ulisesbocchio</groupId> <artifactI ...
- 关于 Linux 中模拟鼠标
问题的背景是我想用自动化脚本来玩 Stardew Valley 的小游戏,刷钱,但是遇到了一系列问题,这里记录我的一些历程. pyautogui/pydirectinput pyautogui 是我第 ...
- C#.NET FRAMEWORK ASP.NET MVC 获取客户端IP
C#.NET FRAMEWORK ASP.NET MVC 获取客户端IP 工具类: using System; namespace CommonUtils { public static class ...
- 请写出常用的linux指令
a.cd /home 进入 '/ home' 目录' b.cd .. 返回上一级目录 c.cd ../.. 返回上两级目录 d.mkdir dir1 创建一个叫做 'dir1' 的目录' e.mkdi ...
- MegaCli命令使用整理
1. 软件安装 rpm -ivh Lib_Utils-1.00-09.noarch.rpm rpm -ivh MegaCli-8.02.21-1.noarch.rpm 2. 常用命令 /opt/Meg ...
- 记一次RocketMQ消费非顺序消息引起的线上事故
应用场景 C端用户提交工单.工单创建完成之后.会发布一条工单创建完成的消息事件(异步消息).MQ消费者收到消息之后.会通知各处理器处理该消息.各处理器处理完后都会发布一条将该工单写入搜索引擎的消息.最 ...
- Python通过GPIO从DHT11温度传感器获取数据
Python通过GPIO从DHT11温度传感器获取数据 设备:树莓派4B.DHT11.杜邦线 DHT11 DHT11是一款有已校准数字信号输出的温湿度传感器. 其精度湿度±5%RH, 温度±2℃,量程 ...
- Mybatis ResultMap复杂对象一对一查询结果映射之association
Mybatis复杂对象映射配置ResultMap的association association:映射到POJO的某个复杂类型属性,比如订单order对象里面包含user对象 表结构 项目结构 pom ...