简单说说SQL中Join的使用

原创 2017年11月09日 00:00:00

640?wx_fmt=jpeg&wxfrom=5&wx_lazy=1

最近工作中,遇到了一起由于慢SQL引起DB CPU > 90% ,数据库hang住。。最终导致其他业务查询统统失败。

       细看下来是由于几张大表Join关联查询引起的,故障本身很常见,不过让我想到有必要讲讲如何规避Join的问题。

       以下的讨论都是基于数据库能力有限的前提下,否则后续的讨论就可以直接忽略了。


首先,我们来谈谈SQL Join的使用场景


1)如果系统存在


高并发、分布式

业务逻辑简单

数据的一致性要求不高

允许延迟读


那么建议在SQL中少使用Join。减少join的目的是在这类业务场景下,除了直观地降低了高并发状态下的资源消耗外,更大的好处是降低了业务之间的耦合,增加了扩展性。服务就可以拆分成多个微服务和多个数据库,便于在一部分负担过重时进行增配;或者直接改为使用缓存等等。


2)如果系统存在


低并发、频繁复杂数据写入

CPU密集而非IO密集

业务逻辑通过数据库处理甚至包含大量存储过程

对一致性与完整性要求很高的系统

需要大量的报表和统计


那么是需要数据库Join的,可以说是无法避免Join。比如部分金融业务、财务系统、企业应用之类,复杂join也是不可避免的,不仅要写,还要写好,才能发挥数据库最大的功用。



对于情况1,我们有以下几种常见的方案来替代Join:


1. 分多次select取不同表的数据,然后在应用代码里做Join;

2. 各自存数据的同时,做一张宽的冗余表,从宽表里取查询数据;

3. 需要Join的数据保存在缓存中(如redis),缓存可以使用主动式(数据修改时更新缓存)或被动式(缓存删除后,读取时才加载);

4. 从独立的用户API接口进行读取。和方法1类似,在代码里做聚合。



对于情况2, 我们的目标是优化Join,提升对应的性能,常见的方案如下:


1.用小结果集驱动大的结果,目的是为了尽可能减少Join语句中的NestedLoop的循环总次数,比如,当两个表(表A和表B)Join的时候,如果表A通过WHERE条件过滤后有10条记录,而表B有20条记录。如果我们选择表A作为驱动表,也就是被驱动表的结果集为20,那么我们通过Join条件对被驱动表(表B)的比较过滤就会有10次。反之,如果我们选择表B作为驱动表,则需要有20次对表A的比较过滤。


2.保证Join语句中被驱动表上Join条件字段已经被索引,保证被驱动表上Join条件字段已经被索引的目的,正是针对上面第1点的考虑,只有让被驱动表的Join条件字段被索引了,才能保证循环中每次查询都能够消耗较少的资源,这也正是优化内层循环的实际优化方法。


3.增大Join_Buffer_Size的大小,MySQL在完成某些join需求的时候(all row join/all index /scan join)为了减少参与join的“被驱动表”的读取次数以提高性能,需要使用到join buffer来协助完成join操作。当join buffer 太小,MySQL不会将该buffer存入磁盘文件而是先将join buffer中的结果与需求join的表进行操作,然后清空join buffer中的数据,继续将剩余的结果集写入buffer中,如此往复,这势必会造成被驱动表需要被多次读取,成倍增加IO访问,降低效率(执行计划中如果现实using join buffer)。如果join语句不是很少的话,个人建议可以适当增大join_buffer_size到1MB左右,如果内存充足可以设置为2MB。


最后一点总结就是,数据不大的时候怎么做都行,就按数据库规范设计最好。数据量大的时候,为了性能就只能牺牲一些规范了。任何的规范都是在特定情况下的某种妥协,脱离了这个环境,就不一定成立了。



扫描二维码或手动搜索微信公众号【架构栈】: ForestNotes

欢迎转载,带上以下二维码即可

                         640?wx_fmt=jpeg


点击阅读原文”,所有【架构栈】近期的架构文章汇总

↓↓↓

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xiedongsheng/article/details/78566588

SQL各种Join连接总结

本文对比总结了SQL中的JOIN之间的联系和区别 1.INNER JOIN or JOIN 2.OUTER JOIN 2.1LEFT OUTER JOIN or LEFT JOIN 2...
  • john_lw
  • john_lw
  • 2017年04月25日 10:20
  • 4996

sql各种Join用法详解

在关系代数中,连接运算是由一个笛卡尔积运算和一个选取运算构成的。首先用笛卡尔积完成对两个数据集合的乘运算,然后对生成的结果集合进行选取运算,确保只把分别来自两个数据集合并且具有重叠部分的行合并在一起。...
  • u012861978
  • u012861978
  • 2016年08月14日 12:58
  • 27359

SQL中的几种join的方法

(1)连接 select * from table1,table2 等价于 select * from table1 cross join table2 select * from table1,ta...
  • coolwzjcool
  • coolwzjcool
  • 2007年03月28日 14:11
  • 917

SQL中的join操作总结(非常好)

1.1.1 摘要 Join是关系型数据库系统的重要操作之一,SQL Server中包含的常用Join:内联接、外联接和交叉联接等。如果我们想在两个或以上的表获取其中从一个表中的行与另一个表中的行...
  • u010159842
  • u010159842
  • 2015年08月25日 16:11
  • 743

SQL中JOIN的用法

join 用于根据两个或多个表中的列之间的关系,从这些表中查询数据。SELECT a.symbol , a.sname , b.tdate , b.close FROM securitycode a ...
  • yanpingsz
  • yanpingsz
  • 2010年06月02日 17:42
  • 10080

关于sql语句中的连接(join)关键字

 关于sql语句中的连接(join)关键字,是较为常用而又不太容易理解的关键字,下面这个例子给出了一个简单的解释 --建表table1,table2: create table table1(...
  • freeideas
  • freeideas
  • 2015年01月19日 11:10
  • 457

大数据量高并发访问SQL优化方法

保证在实现功能的基础上,尽量减少对数据库的访问次数;通过搜索参数,尽量减少对表的访问行数,最小化结果集,从而减轻网络负担;能够分开的操作尽量分开处理,提高每次的响应速度;在数据窗口使用SQL时,尽量把...
  • qq_35624642
  • qq_35624642
  • 2017年02月25日 17:50
  • 3551

SQL JOIN 简单介绍

摘要: join? left join? right join? inner join?outer join?太多join了,您是否了解各种join之间的区别和联系?本文以简单的示例描述各种join之...
  • gschen_cn
  • gschen_cn
  • 2018年02月22日 21:08
  • 19

Spark SQL之Join优化

SparkSQL总体流程介绍 在阐述Join实现之前,我们首先简单介绍SparkSQL的总体流程,一般地,我们有两种方式使用SparkSQL,一种是直接写sql语句,这个需要有元数据库支持,例如...
  • weixin_37136725
  • weixin_37136725
  • 2018年01月06日 15:23
  • 344

关于SQL中用Join in 查询的用法

外联接:外联接可以是左向外联接、右向外联接或完整外部联接。在   FROM   子句中指定外联接时,可以由下列几组关键字中的一组指定:    LEFT   JOIN   或   LEFT   OUTE...
  • wkwanglei
  • wkwanglei
  • 2010年04月11日 16:22
  • 5870
收藏助手
不良信息举报
您举报文章:简单说说SQL中Join的使用
举报原因:
原因补充:

(最多只允许输入30个字)