浅谈 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 多表连接有 ...
随机推荐
- 最好的在线PDF转换工具服务
工作中有时候会碰到需要转换PDF文件的情况,现在网上就要很多免费的在线工具,可以进行PDF文件的转换,下面就来介绍一些可以直接在浏览器中将文档.电子表格.和图片转换为PDF或者互相转换的服务工具. ...
- RTOS入门
RTOS是什么? RTOS是一款操作系统,相当于Windows\Linux 分为ucos FreeRTOS RT-Thread LiteOS 比裸机开发的优势在于,多任务系统,不必串行 临界区 临界区 ...
- 如何实现sm3加密
SM3加密应用 何为sm3加密? SM3是由中国国家密码管理局设计的一种密码杂凑函数,类似于SHA-256和MD5等国际标准的散列算法.SM3算法是中国国家标准<GB/T 32905-2016 ...
- Mesh快连
Mesh快连 一.名词解释 Mesh快连是一种由多个节点组成的网络系统,这些节点可以相互连接,形成一个"网状"的结构. 二.如何使用 有线Mesh: 网络拓扑: 设备版本:3.7. ...
- jquery中封装了三种ajax请求方式
// jQuery中封装了3种 ajax 请求方式 // 1, get请求方式 // 2, post请求方式 // 3, 综合请求方式 ...
- CF题解合集
CF 比赛题解合集 目录 CF 比赛题解合集 1952 A. Ntarsis' Set B. Imbalanced Arrays C. Ina of the Mountain D. Miriany a ...
- [SWPUCTF 2021 新生赛]gift_F12
首先我们打开环境会发现花里胡哨的,而题目中有提示:F12,所以我们直接F12查看源码 然后ctrl+f信息检索flag.直接找到flag提交 但要注意提交格式为NSSCTF{}
- 前端使用 Konva 实现可视化设计器(14)- 折线 - 最优路径应用【代码篇】
话接上回<前端使用 Konva 实现可视化设计器(13)- 折线 - 最优路径应用[思路篇]>,这一章继续说说相关的代码如何构思的,如何一步步构建数据模型可供 AStar 算法进行路径规划 ...
- docker容器单机编排
随着网站架构的升级,容器也使用的越发频繁,应用服务和容器间的关系也越发复杂. 这就要求研发人员能够更好的方法去管理数量较多的容器服务,而不能手动的去挨个管理. 例如一个LNMP的架构,就得部署web服 ...
- Spring AOP 中@Pointcut的用法(多个Pointcut)
Spring AOP 中@Pointcut的用法(多个Pointcut) /** swagger切面,分开来写 **/ @Aspect @Component public class ApiOpera ...