承接国内外服务器租用托管、定制开发、网站代运营、网站seo优化托管接单、网站代更新,新老站点皆可!!咨询QQ:3787320601

性能优化:告知你SQL为何不建议履行超过3表以上的多表关联查询

管理员 2023-06-25 08:19:12 互联网圈 13 ℃ 0 评论 6323字 收藏

概述:前段时间在跟其他公司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):远程进程调用,它是一种通过网络从远程计算机程序上要求服务,而不需要了解底层网络技术的思想

到此这篇关于SQL为何不建议履行超过3表以上的多表关联查询的文章就介绍到这了,更多相关SQL多表关联查询内容请搜索之前的文章或继续浏览下面的相关文章希望大家以后多多支持!

文章来源:丸子建站

文章标题:性能优化:告知你SQL为何不建议履行超过3表以上的多表关联查询

https://www.wanzijz.com/view/58994.html

X

截屏,微信识别二维码

微信号:weimawl

(点击微信号复制,添加好友)

打开微信