为什么不建议使用多表join(什么情况下使用多表连接)
yuyutoo 2025-03-19 04:01 10 浏览 0 评论
前言
三年前在一家公司和开发团队的架构师合作过,一起写过代码。让我真的很难受啊,这个架构师写的代码很多逻辑都写到SQL里面,各种连表查询,SQL 非常的复杂,每次我去维护都得看好久它这个SQL逻辑。
回到最近,现在有个小伙儿班也是喜欢在SQL里面写逻辑,各种关联查询,甚至写的SQL连一万的数据连都支持不了。
所以我们的SQL尽量的简洁,少用多表关联查询。
为什么不建议使用多表join?
最主要的原因就是join的效率比较低
当然几万、几十万的数据量 连个几张表影响不大,用join查询是没啥问题的。要谈性能肯定是需要大量数据做支撑的。
MySQL是使用了嵌套循环(Nested-Loop Join)的方式来实现关联查询的,就是要通过两层循环,用第一张表做外循环,第二张表做内循环,外循环的每一条记录跟内循环中的记录作比较,符合条件的就输出。
- 性能问题:
- 多表 JOIN 会增加查询的复杂性,可能导致性能下降,特别是在数据量大时。
- 数据库需要在执行查询时处理更多的行和列,这可能导致更高的 I/O 操作和内存使用。
- 可读性和维护性:
- 复杂的 JOIN 查询会使 SQL 语句变得难以理解,导致维护成本增加。
- 当查询需要频繁修改时,复杂的 JOIN 会让代码更容易出错。
- 索引利用率:
- 多表 JOIN 可能会导致数据库无法有效利用索引,影响查询的优化。
- 如果 JOIN 的字段没有适当的索引,查询性能会显著下降。
- 锁竞争:
- 多表 JOIN 可能导致更长时间的行锁或表锁,从而增加锁竞争的可能性,影响并发性能。
- 数据完整性:
- 复杂的 JOIN 查询可能掩盖数据问题或不一致性,使得调试较为困难。
- 难以确保在 JOIN 查询中返回的数据符合业务逻辑和数据完整性要求。
如何优化:
- 分解查询:在内存中自己做关联,即先从数据库中把数据查出来之后,再次查询,然后再进行数据封装。
- 考虑数据冗余:在某些情况下,可以考虑数据冗余来减少 JOIN 的需要。
- 宽表:就是基于一定的join关系,把数据库中多张表的数据打平做一张大宽表,可以同步到ES或者干脆直接在数据库中直接查都可以
什么是hash join(扩展阅读)
mysql8.0.18 以前join查询使用Nested-Loop Join算法实现
Nested-Loop Join:嵌套循环连接,如果有2张表join的话,复杂度最高是O(n^2),3张表则是O(n^3),表中的数据量越多,JOIN的效率会呈指数级下降。
MySQL 8.0.18中优化了join查询,新增了 hash join算法。 Hash Join 是一种高效的联表查询算法,通常用于处理较大数据集的连接操作。下面将详细介绍 Hash Join 的原理,并通过示例图解说明其查询步骤。
Hash Join 原理
Hash Join 的基本原理是将一个表的数据构建成一个哈希表,然后利用该哈希表来查找另一个表中匹配的行。其主要分为两个阶段:
- 构建阶段(Build Phase):
- 选择一个较小的表(称为构建表)来创建哈希表。
- 根据连接条件的键值计算哈希值,并将这些键值和对应的行存储在哈希表中。
- 探测阶段(Probe Phase):
- 对另一个表(称为探测表)逐行读取数据。
- 对于探测表中的每一行,计算连接字段的哈希值,并在哈希表中查找匹配的行。
- 如果找到匹配,则将匹配的行组合在一起,形成结果集。
Hash join 案例
假设我们有两个表:
表 A:
ID | Name |
1 | Alice |
2 | Bob |
3 | Charlie |
表 B:
ID | Age |
1 | 25 |
2 | 30 |
4 | 40 |
我们希望通过 ID 字段将这两个表连接起来。
步骤 1: 构建哈希表
选择表 A 作为构建表。我们将根据 ID 字段创建哈希表。
- 对于 ID = 1,哈希值为 hash(1),存储为 {1: Alice}。
- 对于 ID = 2,哈希值为 hash(2),存储为 {2: Bob}。
- 对于 ID = 3,哈希值为 hash(3),存储为 {3: Charlie}。
哈希表:
{
1: Alice,
2: Bob,
3: Charlie
}
步骤 2: 探测阶段
接下来,我们对表 B 进行探测,查找与哈希表中的行匹配的行。
- 对于 ID = 1,计算 hash(1),在哈希表中找到匹配,结果为 (1, Alice, 25)。
- 对于 ID = 2,计算 hash(2),在哈希表中找到匹配,结果为 (2, Bob, 30)。
- 对于 ID = 4,计算 hash(4),在哈希表中未找到匹配。
匹配之后做聚合就得到结果集了
这里的hash表是存在内存中的,内存是有限制的,超过阈值之后就会走 磁盘Hash join 的算法
磁盘hash join
如果驱动表中的数据量超过阈值,就会走磁盘hash join的算法。将驱动表拆分成多个哈希区(或桶),每个桶存储在磁盘上。读取磁盘上的hash桶分别加载到内存,进行探测匹配,探测完成释放当前内存桶,继续从磁盘上读取下一个hash桶进行探测匹配,直到磁盘上所有的hash桶都处理完毕。
总结
在实际开发中,尽量减少多表join查询,保持SQL的逻辑清晰,这样不仅能提高性能,还有利于维护。
感谢佬们的一键三连+关注 !!!
Hash JOIN官方资料:
相关推荐
- 《保卫萝卜2》安卓版大更新 壕礼助阵世界杯
-
《保卫萝卜2:极地冒险》本周不仅迎来了安卓版本的重大更新,同时将于7月4日本周五,带来“保卫萝卜2”安卓版本世界杯主题活动的火热开启,游戏更新与活动两不误。一定有玩家会问,激萌塔防到底进行了哪些更新?...
- 儿童手工折纸:胡萝卜,和孩子一起边玩边学carrot
-
1、准备两张正方形纸,一橙一绿,对折出折痕。2、橙色沿其中一条对角线如图折两三角形。3、把上面三角折平,如图。4、绿色纸折成三角形。5、再折成更小的三角形。6、再折三分之一如图。7、打开折纸,压平中间...
- 《饥荒》食物代码有哪些(饥荒最新版代码总汇食物篇)
-
饥荒游戏中,玩家们需要获取各种素材与食物,进行生存。玩家们在游戏中,进入游戏后按“~”键调出控制台使用代码,可以直接获得素材。比如胡萝卜的代码是carrot,玉米的代码是corn,南瓜的代码是pump...
- Skyscanner:帮你找到最便宜机票 订票不求人
-
你喜欢旅行吗?在合适的时间、合适的目的地,来一场说走就走的旅行?机票就是关键!Skyscanner这款免费的手机应用,在几秒钟内比较全球600多家航空公司的航班安排、价格和时刻表,帮你节省金钱和时间。...
- 小猪佩奇第二季50(小猪佩奇第二季英文版免费观看)
-
Sleepover过夜Itisnighttime.现在是晚上。...
- 我在民政局工作的那些事儿(二)(我在民政局上班)
-
时间到了1997年的秋天,经过一年多的学习和实践,我在处理结婚和离婚的事情更加的娴熟,也获得了领导的器重,所以我在处理平时的工作时也能得心应手。这一天我正在离婚处和同事闲聊,因为离婚处几天也遇不到人,...
- 夏天来了就你还没瘦?教你不节食13天瘦10斤的哥本哈根减肥法……
-
好看的人都关注江苏气象啦夏天很快就要来了你是否和苏苏一样身上的肉肉还没做好准备?真是一个悲伤的故事……下面这个哥本哈根减肥法苏苏的同事亲测有效不节食不运动不反弹大家快来一起试试看吧~DAY1...
- Pursuing global modernization for peaceful development, mutually beneficial cooperation, prosperity for all
-
AlocalworkeroperatesequipmentintheChina-EgyptTEDASuezEconomicandTradeCooperationZonei...
- Centuries-old tea road regains glory as Belt and Road cooperation deepens
-
FUZHOU/ST.PETERSBURG,Oct.2(Xinhua)--NestledinthepicturesqueWuyiMountainsinsoutheastChi...
- Ftrace function graph简介(flat function)
-
引言由于android开发的需要与systrace的普及,现在大家在进行性能与功耗分析时候,经常会用到systrace跟pefetto.而systrace就是基于内核的eventtracing来实...
- JAVA历史版本(java各版本)
-
JAVA发展1.1996年1月23日JDK1.0Java虚拟机SunClassicVM,Applet,AWT2.1997年2月19日JDK1.1JAR文件格式,JDBC,JavaBea...
- java 进化史1(java的进阶之路)
-
java从1996年1月第一个版本诞生,到2022年3月最新的java18,已经经历了27年,整整18个大的版本。很久之前有人就说java要被淘汰,但是java活到现在依然坚挺,不知道java还能活...
- 学习java第二天(java学完后能做什么)
-
#java知识#...
你 发表评论:
欢迎- 一周热门
- 最近发表
-
- 《保卫萝卜2》安卓版大更新 壕礼助阵世界杯
- 儿童手工折纸:胡萝卜,和孩子一起边玩边学carrot
- 《饥荒》食物代码有哪些(饥荒最新版代码总汇食物篇)
- Skyscanner:帮你找到最便宜机票 订票不求人
- 小猪佩奇第二季50(小猪佩奇第二季英文版免费观看)
- 我在民政局工作的那些事儿(二)(我在民政局上班)
- 夏天来了就你还没瘦?教你不节食13天瘦10斤的哥本哈根减肥法……
- Pursuing global modernization for peaceful development, mutually beneficial cooperation, prosperity for all
- Centuries-old tea road regains glory as Belt and Road cooperation deepens
- 15 THE NUTCRACKERS OF NUTCRACKER LODGE (CONTINUED)胡桃夹子小屋里的胡桃夹子(续篇)
- 标签列表
-
- mybatis plus (70)
- scheduledtask (71)
- css滚动条 (60)
- java学生成绩管理系统 (59)
- 结构体数组 (69)
- databasemetadata (64)
- javastatic (68)
- jsp实用教程 (53)
- fontawesome (57)
- widget开发 (57)
- vb net教程 (62)
- hibernate 教程 (63)
- case语句 (57)
- svn连接 (74)
- directoryindex (69)
- session timeout (58)
- textbox换行 (67)
- extension_dir (64)
- linearlayout (58)
- vba高级教程 (75)
- iframe用法 (58)
- sqlparameter (59)
- trim函数 (59)
- flex布局 (63)
- contextloaderlistener (56)