浅谈 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 连表查询的更多相关文章

  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. Kubernetes Cluster部署

    1.基本环境说明 ip: 192.168.115.149 主机名:node1    CentOS Linux release 7.9.2009,内核版本为3.10.0-1160.81.1.el7.x8 ...

  2. VALL-EX下载介绍:只需3秒录音,即可克隆你的声音

    VALL-EX是一个强大和创新的多语言文本转语音模型,支持对中文.英文和日语的语音进行合成和克隆,使用者只需上传一段3-10秒的录音,就可以生成高质量的目标音频,同时保留了说话人的声音.情感和声学环境 ...

  3. github无法访问的问题

    Windows10 通过nslookup命令获取GitHub域名服务器地址,然后ping该地址 nslookup github.com ping 域名服务器地址 发现20.205.243.166能稳定 ...

  4. 分布式定理--CAP定理

    cap定理指的是,在一个分布式系统中,只能满足cap中的两项. C consistency 一致性 A availability 可用性 P partition tolerance 分区可容错性 -- ...

  5. 认识mongodb

    Mongodb是一个介于关系数据库和非关系数据库之间的产品(Nosql),是非关系数据库当中功能最丰富,最像关系数据库的,语法有点类似javascript面向对象的查询语言,它是一个面向集合的,模式自 ...

  6. 剑指Offer-65.矩阵中的路径(C++/Java)

    题目: 请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径.路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子.如果一条路径经过了矩阵中的 ...

  7. (二)requests-爬取国家药监局生产许可证数据

    首先访问这个页面 url = 'http://125.35.6.84:81/xk/' 我们的目标是抓取这里的每一个企业的详情页数据,但是可以发现这里只有企业的简介信息,所以这就意味着我们要发送两次ge ...

  8. Docker PHP启用各种扩展笔记

    注意 如果apt-get install命令无法安装依赖,请先执行apt update更新依赖信息 启用ZIP扩展 原作者地址:找不到了... # 安装依赖库 $ apt-get install -y ...

  9. Spark Structured Streaming(二)实战

    5. 实战Structured Streaming 5.1. Static版本 先读一份static 数据: val static = spark.read.json("s3://xxx/d ...

  10. 一次STM32进入HardFault_Handler 的解决情况

    STM32进入HardFault_Handler调试 --- title: STM32进入HardFault_Handler调试 date: 2020-06-18 10:26:48 categorie ...