概述

前段时间在跟其他公司DBA交流时谈到了mysql跟PG之间在多表关联查询上的一些区别,相比之下mysql只有一种表连接类型:嵌套循环连接(nested-loop),不支持排序-合并连接(sort-merge join)与散列连接(hash join),而PG是都支持的,而且mysql是往简单化方向去设计的,如果多个表关联查询(超过3张表)效率上是比不上PG的。

摘要

  • 不超过3层是为了效率。

  • 更通用 ,更好为了分布式做准备。

下面也对mysql多表关联这个特性简单探讨下~

MySQL多表关联查询效率高点还是多次单表查询效率高?

A,B两个表数据规模十几万,数据规模都不大,单机MySQL够用了,在单机的基础上要关联两表的数据,先说一个极端情况,A,B两个表都没有索引,并且关联是笛卡尔积,那关联结果会爆炸式增长,可能到亿级别,这个时候网络IO成了瓶颈,这个时候两次十万行结果集的拉去可能远小于1次亿级别的结果集的拉取,那么将关联合并拉到service层做更快。

但实际业务中一般不会有这么蠢的行为,一般关联会有连接条件,并且连接条件上会有索引,一般是有一个结果集比较小,拿到这个结果集去另一张表去关联出其它信息。

如果放到service层去做,最快的方式是,先查A表,得到一个小的结果集,一次rpc,再根据结果集,拼凑出B表的查询条件,去B表查到一个结果集,再一次rpc,再把结果集拉回service层,再一次rpc,然后service层做合并,3次rpc。

如果用数据库的join,关联结果拉回来,一次rpc,帮你省了两次rpc,当然数据库上做关联更快,对应到数据库就是一次blk nested loop join,这是业务常用情况。

但是确实大多数业务都会考虑把这种合并操作放到service层,一般是有以下几方面考虑:

第一

单机数据库计算资源很贵,数据库同时要服务写和读,都需要消耗CPU,为了能让数据库的吞吐变得更高,而业务又不在乎那几百微妙到毫秒级的延时差距,业务会把更多计算放到service层做,毕竟计算资源很好水平扩展,数据库很难啊,所以大多数业务会把纯计算操作放到service层做,而将数据库当成一种带事务能力的kv系统来使用,这是一种重业务,轻DB的架构思路

第二

很多复杂的业务可能会由于发展的历史原因,一般不会只用一种数据库,一般会在多个数据库上加一层中间件,多个数据库之间就没办法join了,自然业务会抽象出一个service层,降低对数据库的耦合。

第三

对于一些大型公司由于数据规模庞大,不得不对数据库进行分库分表,对于分库分表的应用,使用join也受到了很多限制,除非业务能够很好的根据sharding key明确要join的两个表在同一个物理库中。而中间件一般对跨库join都支持不好。

举一个很常见的业务例子,在分库分表中,要同步更新两个表,这两个表位于不同的物理库中,为了保证数据一致性,一种做法是通过分布式事务中间件将两个更新操作放到一个事务中,但这样的操作一般要加全局锁,性能很捉急,而有些业务能够容忍短暂的数据不一致,怎么做?

让它们分别更新呗,但是会存在数据写失败的问题,那就起个定时任务,扫描下A表有没有失败的行,然后看看B表是不是也没写成功,然后对这两条关联记录做订正,这个时候同样没法用join去实现,只能将数据拉到service层应用自己来合并了。。。

到这里答案就很清楚了~

对关联查询进行分解

很多高性能的应用都会对关联查询进行分解。

简单地,可以对每个表进行一次单表查询,然后将结果在应用程序中进行关联。例如,下面这个查询:

select * from tag
join tag_post on tag_post.tag_id=tag.id
join post on tag_post.post_id=post.id
where tag.tag=’mysql’;

可以分解成下面这些查询来代替:

Select * from tag where tag=’mysql’;
Select * from tag_post where tag_id=1234;
Select * from post where id in(123,456,567,9989,8909);

为什么会这样做呢?原本一条查询,这里却变成了多条查询,返回结果又是一模一样。

事实上,用分解关联查询的方式重构查询具有如下优势:

  • 让缓存的效率更高。

  • 许多应用程序可以方便地缓存单表查询对应的结果对象。另外对于MySQL的查询缓存来说,如果关联中的某个表发生了变化,那么就无法使用查询缓存了,而拆分后,如果某个表很少改变,那么基于该表的查询就可以重复利用查询缓存结果了。

  • 将查询分解后,执行单个查询可以减少锁的竞争。

  • 在应用层做关联,可以更容易对数据库进行拆分,更容易做到高性能和可扩展。

  • 查询本身效率也可能会有所提升

  • 可以减少冗余记录的查询。

  • 更进一步,这样做相当于在应用中实现了哈希关联,而不是使用MySQL的嵌套环关联,某些场景哈希关联的效率更高很多。

解释

RPC(Remote Procedure Call):远程过程调用,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的思想

往期推荐

纯干货 | 从淘宝到云端的高可用架构演进

好的代码结构是什么样的?

到底什么是"超融合"呢?

(珍藏版)55 个细节帮你做好Java的 性能优化

面试官:请你说说k8s 和 Docker的区别?

架构师:关系型数据库设计技巧?

因为Kafka 宕机,同事 写了篇Kafka 高可用原理复盘!

回复干货】获取精选干货视频教程

回复加群】加入疑难问题攻坚交流群

回复mat】获取内存溢出问题分析详细文档教程

回复赚钱】获取用java写一个能赚钱的微信机器人

回复副业】获取程序员副业攻略一份

好文请点赞+分享

为什么禁止超过三张表 join,原理是什么?相关推荐

  1. 为什么阿里巴巴规定禁止超过三张表 join?

    欢迎关注方志朋的博客,回复"666"获面试宝典 概述 前段时间在跟其他公司DBA交流时谈到了mysql跟PG之间在多表关联查询上的一些区别,相比之下mysql只有一种表连接类型:嵌 ...

  2. 为什么阿里巴巴规定禁止超过三张表 join

    点击"终码一生",关注,置顶公众号 每日技术干货,第一时间送达! 1.概述 前段时间在跟其他公司DBA交流时谈到了mysql跟PG之间在多表关联查询上的一些区别,相比之下mysql ...

  3. 阿里规定超过三张表禁止JOIN,为啥呢?

    作者 | e71hao 来源 | http://blog.itpub.net/30393770/viewspace-2650450/ 一. 问题提出 <阿里巴巴JAVA开发手册>里面写超过 ...

  4. 涨知识了!阿里规定超过三张表禁止join,为啥?

    点击上方"菜鸟学Python",选择"星标"公众号 重磅干货,第一时间送达 作者:e71hao blog.itpub.net/30393770/viewspac ...

  5. oracle中join另一个表后会查询不出一些数据_阿里规定超过3张表,禁止JOIN,为何?

    一. 问题提出 <阿里巴巴JAVA开发手册>里面写超过三张表禁止join,这是为什么? 二.问题分析 对这个结论,你是否有怀疑呢?也不知道是哪位先哲说的不要人云亦云,今天我设计sql,来验 ...

  6. sql 语句left join关联超过2张表时,随着left join一路向左,永远只能是最左边的关联表与新表关联吗?还是母表可以一直on下去?

    今天这个帖子要解决一个问题:oracle数据库表间通过left join关联超过2张表时,随着left join一路向左,永远只能是最左边的关联表与新表关联吗?还是母表可以一直on 下去? 利用sql ...

  7. Hive SQL 小表与大表Join 原理与实操

    一.案例演示 1)没有使用map join -- a 表是大表,数据量是百万级别 -- b 表是小表,数据量在百级别 select a.field1 as field1,b.field2 as fie ...

  8. Mysql数据库使用:学生选课系统,其中设计到三张表,分别为学生表,课程表,学生和课程对应的关联表。

    Mysql数据库使用 练习内容:主要针对学生选课系统而设计,其中设计到三张表,分别为学生表,课程表,学生和课程对应的关联表. 学生表主要用于存储学生信息,包括姓名,性别,地址,电话等信息 课程表主要用 ...

  9. 产品经理最最最最需要关切的三张表

    作者:刘雨 全文共 4141 字,阅读需要 9 分钟 ---- / BEGIN / ---- 我们知道在财务系统里有三张表:「 资产负债表 」.「 利润表 」和 「 现金流量表 」. 资产负债表反映公 ...

最新文章

  1. 干货|简单理解逻辑回归基础
  2. http请求gmt时间_从Chrome源码看HTTP
  3. python cocos2d菜鸟教程_(译)cocos2d菜单教程:第一部分
  4. 面向对象--第三部分
  5. ecu故障现象_【案例】柴油电喷车维修故障案例
  6. arcgis server 10.4 安装与授权
  7. mysql数据库改成支持中文_修改Mysql编码支持中文
  8. util.java_TelnetUtil.java
  9. java明文发送_使用java MD5加密网络明文
  10. 庆祝自开博来首篇浏览数过万的随笔诞生 - [原创]从程序员角度分析安徽电信HTTP劫持的无耻行径......
  11. Android 版本对于 API
  12. tar包zip的拆分与合并
  13. 服务器开启谷歌BBR加速网络
  14. C++程序设计试题及答案解析(一)
  15. 苹果手机投屏到电脑大屏幕上的方法
  16. Mac Chrome搜索引擎突然变成了Yahoo?!SearchToolHelper控制了我的搜索引擎
  17. iPhone媒体服务器修改,出现Apple媒体服务条款与条件已更改是怎么回事如何解决...
  18. React Toolkit使用
  19. 分组卷积与DW卷积、Residuals与Inverted Residuals、bottleneck与linearbottleneck
  20. 测试软件要求规范 (SRS)

热门文章

  1. c++课程设计图书馆管理系统总结
  2. python plc fx5u_三菱PLC的FX5U系列参数与定位点
  3. 1.已有一个已排好序的数组,今输入一个数,要求按原来排序的规律将它插入数组中。
  4. 2017级算法第二次上机-C.芸如的入学测试
  5. oracle查询谁修改了数据ip,查询oracle特定表修改的用户及IP信息
  6. 5.4 塑造IT人的专业核心能力——《逆袭大学》连载
  7. ICESat2学习笔记5 :ICESat-2数据下载
  8. python pandas的read_html方法爬取网页表格
  9. phpmail通过qq发邮箱失败_请问phpmailer发送Gmail总是失败是什么原因,qq邮件可以发送出去...
  10. 为Go语言GC正名-20秒到100微妙的演变史