目录

  • 一、概述
  • 二、讨论

一、概述

前段时间在跟其他公司 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);

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

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

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

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

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

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

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

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

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

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

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

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

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

  5. MySQL CASE WHEN 根据一个表的字段值不同关联查询两张不同的表【子查询】

    2019独角兽企业重金招聘Python工程师标准>>> SELECT CASE WHEN t.name_a != ''THEN t.name_aWHEN t.name_b != '' ...

  6. MySQL多表关联查询效率高点还是多次单表查询效率高,为什么?

    这里写目录标题 MySQL多表关联查询对比多次单表查询,哪个效率高? 疑问: 高手解答: <阿里巴巴JAVA开发手册>里面写超过三张表禁止join 这是为什么?这样的话那sql要怎么写? ...

  7. (四)MySQL学习笔记——多表设计、多表查询、多表查询练习题

    文章目录 一.多表设计 1.一对一设计 2.一对多设计 3.多对多设计 二.多表查询 多表查询前的数据准备 1.内连接查询 2.外连接查询 3.子查询 4.自关联查询 三.多表查询练习 一.多表设计 ...

  8. 神奇的 SQL 之 联表细节 → MySQL JOIN 的执行过程(二)

    开心一刻 一头母牛在吃草,突然一头公牛从远处狂奔而来说:"快跑啊!!楼主来了!" 母牛说:"楼主来了关我屁事啊?" 公牛急忙说:"楼主吹牛逼呀!&qu ...

  9. MySQL IN、Exist关联查询时,我们为什么建议小表驱动大表?

    有的时候我们在操作数据库时会将两个或多个数据表关联起来通过一些条件筛选数据,在关联表时我们要遵循一些原则,这样会使我们编写的SQL 语句在效率上快很多. 一.优化原则 小表驱动大表,即小的数据集驱动大 ...

最新文章

  1. Exchange2000需要创建的3个SMTP服务实例
  2. Android Studio 1.0 苹果电脑安装配置
  3. 生产性企业CO部分月结流程及系统步骤
  4. EMNLP'21 | 检索式对话情感回复
  5. 使用STM32固件库开发GD32 汇总
  6. Codeforces1196D2
  7. 微信dat转码-微信数据库解密-dat批量查看
  8. 盖世帝尊 I 分享(一叶青天)
  9. IDEA--安装、使用
  10. scala groupby用法
  11. 计算机科技英语一千字作文,关于科技的英语作文3篇
  12. 修改默认的“baked”产生的HTML模板
  13. 企业网站关键词优化的步骤
  14. 毕业论文的文件压缩的一次实践,解决文件大小超出范围
  15. Element ui+vue前端框架组件主题美化后台管理系统模板html
  16. 自媒体平台运营的感悟
  17. IDM+百度云链下载网盘资源
  18. C++ COleDateTime
  19. 网络工程师笔记——密钥分配
  20. 需要近期熟悉的表_2019_3_18

热门文章

  1. 冬天别忘晒太阳[整理]
  2. CUDA软件架构—网格(Grid)、线程块(Block)和线程(Thread)的组织关系以及线程索引的计算公式
  3. 叮咚~ 你有一份令人心动的offer待查收【cv君独家内推】
  4. html在字体两边加直线,css怎么在文字两边加上横线
  5. Linux下,为应用程序添加桌面图标(ubuntu18.4)
  6. Planned Contrasts and Post hoc Tests 多重检验校正
  7. python对于会计的好处_学好会计学的作用及意义
  8. Cassandra Cql
  9. live2d_Live2D解锁丨SR羁绊复刻,生日定制服装上架!
  10. TencentOS-Tiny在苹果MacOS初上手