概述

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

下面也对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);

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

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

  1. 让缓存的效率更高。
  2. 许多应用程序可以方便地缓存单表查询对应的结果对象。另外对于MySQL的查询缓存来说,如果关联中的某个表发生了变化,那么就无法使用查询缓存了,而拆分后,如果某个表很少改变,那么基于该表的查询就可以重复利用查询缓存结果了。
  3. 将查询分解后,执行单个查询可以减少锁的竞争。
  4. 在应用层做关联,可以更容易对数据库进行拆分,更容易做到高性能和可扩展。
  5. 查询本身效率也可能会有所提升
  6. 可以减少冗余记录的查询。
  7. 更进一步,这样做相当于在应用中实现了哈希关联,而不是使用MySQL的嵌套环关联,某些场景哈希关联的效率更高很多。

转载于:https://www.cnblogs.com/Java-no-1/p/11019615.html

面试官:为什么mysql不建议执行超过3表以上的多表关联查询?相关推荐

  1. mysql一次查询无关联多个表_面试官:为什么mysql不建议执行超过3表以上的多表关联查询?...

    点关注,不迷路:持续更新Java架构相关技术及资讯热文!!! 概述 前段时间在跟其他公司DBA交流时谈到了mysql跟PG之间在多表关联查询上的一些区别,相比之下mysql只有一种表连接类型:嵌套循环 ...

  2. 为什么 MySQL 不建议执行超过 3 表以上的多表关联查询?

    目录 一.概述 二.讨论 一.概述 前段时间在跟其他公司 DBA 交流时谈到了 MySQL 与 PG之间在多表关联查询上的一些区别,相比之下 MySQL 只有一种表连接类型:嵌套循环连接 (neste ...

  3. 为什么mysql不建议执行超过3表以上的多表关联查询?

    概述 前段时间在跟其他公司DBA交流时谈到了mysql跟PG之间在多表关联查询上的一些区别,相比之下mysql只有一种表连接类型:嵌套循环连接(nested-loop),不支持排序-合并连接(sort ...

  4. 美团面试官:为什么不建议把数据库部署在Docker容器内?

    点击上方蓝色字体,选择"标星公众号" 优质文章,第一时间送达 关注公众号后台回复pay或mall获取实战项目资料+视频 年初送15.6英寸笔记本电脑,吃鸡超级爽,不爱可折现!! 作 ...

  5. 【227期】面试官:MySQL 数据查询太多会 OOM 吗?

    点击上方"Java精选",选择"设为星标" 别问别人为什么,多问自己凭什么! 下方有惊喜,留言必回,有问必答! 每天 08:15 更新文章,每天进步一点点... ...

  6. 字节面试官:一条sql执行慢的原因?如何优化?

    点击上方"程序猿技术大咖",关注并选择"设为星标" 回复"加群"获取入群讨论资格! 作为二本上岸大厂的后端应届生,深知没人带一路摸索的艰辛, ...

  7. 面试官:MySQL 表设计要注意什么?

    点击上方"方志朋",选择"设为星标" 做积极的人,而不是积极废人 来自公众号:孤独烟 引言 大家应该知道烟哥最近要(tiao 咳咳咳),嗯,不可描述! 随手讲其 ...

  8. 征服Java面试官!mysql索引树结构

    美团技术一面20分钟 晚7点,因为想到下周一才面试,我刚准备出去打个羽毛球,北京的电话就来了.面试官各种抱歉,说开会拖延了. 1.自我介绍 说了很多遍了,很流畅捡重点介绍完. 2.问我数据结构算法好不 ...

  9. 【176期】面试官:MYSQL 表数据 delete 删除后,为何还占用存储空间?

    点击上方"Java精选",选择"设为星标" 别问别人为什么,多问自己凭什么! 下方有惊喜,留言必回,有问必答! 每天 08:35 更新文章,每天进步一点点... ...

最新文章

  1. python 人脸检测
  2. 网络营销外包——网络营销外包专员浅析提升用户体验从哪入手?
  3. IOS 程序内调用本地打电话功能-make a phone call
  4. spoj 375 Query on a tree
  5. 条件变量 ---C++17 多线程
  6. 用python处理excel表格_如何用python处理excel数据 | 用python处理excel表格数据类型
  7. h:commandButton
  8. H264帧的分析sps pps
  9. Oracle 正则表达式函数-REGEXP_SUBSTR 使用例子
  10. OpenCV读取一张图片,并将其转换为灰度图像显示
  11. java反编译有什么用处_Java反编译工具有什么用,Java反编译工具使用解析
  12. 【原创】docker在Ubuntu下1小时快速学习
  13. excel如何批量查询手机号归属地
  14. C语言单片机串转并,74ls164与单片机的串并转换(串转并\串进并出)
  15. 太真实,北上广深年薪20W、30W、40W的程序员的生活状态!
  16. 低功耗4g无线视频服务器,低功耗4G+AI+IOT视频安防行业的首选
  17. web期末大作业 使用HTML+CSS制作蓝色版爱宠之家带留言板(5页)
  18. PMPBOK6之项目管理的33个文件
  19. vue/uniapp 强制组件重新渲染的几种方式
  20. BIND 的SRV记录

热门文章

  1. openwrt安装oracle,Openwrt安装软件的方法-tomcat 随笔小记-install ubuntu 12.04 in virtualbox_169IT.COM...
  2. 显卡mx150和230哪个好_MX250显卡等于GTX1050?笔记本显卡MX250和MX150的区别对比
  3. 计算机知识幼儿园,幼儿园中班计算机教学工作计划
  4. react native的页面整体下拉刷新
  5. 我三年开发经验,从字节跳动抖音离职后,原理+实战+视频+源码
  6. 【C++ STL】vector库使用方法
  7. python【数据结构与算法】选数问题(指定值求和——递归)
  8. python【蓝桥杯vip练习题库】ADV-96复数求和
  9. 解决ubuntu系统中输入sudo passwd root,之后,提示输入新密码时,输不进去
  10. Binary Matrix Transform