union和unionall的性能差别居然这么⼤!!
最近做个项⽬,要把我们系统中的⽤户数据,按照别⼈系统的格式要求⽣成数据⽂本,导⼊到别的系统中。
我们系统的⽤户数据主要存放在两个表中,⽤户信息表(user)和⽤户附加信息表(extend)。user表中主要是⽤户id,⽤户昵称、⽤户名等信息,extend表中主要是⼿机号、⾝份证、核⼼客户号码等信息。每个表的主键都是⽤户id(字段名为uid),分别有1.6亿数据,关联查询导出即可。
查询要求
核⼼客户号(cusnum)有效的⽤户,即不为空、不为零。
核⼼客户号(cusnum)为空,⾝份三要素(姓名name、证件类型certType、证件号码certNum)有效的情况。
sql中union多表合并SQL语句
查询SQL⾮常简单,分别将满⾜条件的数据查出来做个合并,导出⾄指定⽂件即可。
// 核⼼客户号有效
select ...
from user u inner join extend e
on u.uid=e.uid
where e.cusnum IS NOT NULL and e.cusnum != '' and e.cusnum != 0
union
// 核⼼客户号为空,⾝份三要素有效
select ...
from user u inner join extend e
on u.uid=e.uid
where (e.cusnum IS NULL or e.cusnum = '' or e.cusnum = 0)
and (e.name IS NOT NULL and e.name != '')
and (e.certType IS NOT NULL Type != '')
and (e.certNum IS NOT NULL Num != '')
into outfile '/'
但是使⽤这个SQL,导出全部1.6亿的数据竟然⽤了14个⼩时
这个时间已经远远超过了投产的时间窗⼝,1.6亿数据虽然会慢,但没道理会这么慢呀。
把两个SQL分别执⾏导出,每个语句执⾏了不到20分钟就完成了,但是使⽤union在⼀起竟然会变得这么慢。
union机制
随后,我就查了查mysql的union机制,才知道union不仅对多个sql的查询结果做了合并,还在合并的基础上做了默认排序,同时还去除了重复⾏。1.6亿的数据进⾏排序、归并,想想就头疼。
如果不对查询结果进⾏排序、去重的话,可以使⽤union all。
union all 只是简单的将两个结果合并后就返回。如果返回的两个结果集中有重复的数据,那么返回的
结果集就会包含重复的数据了。
在我们的这个场景中,第⼀个语句的条件是cusnum有效,第⼆个语句的查询条件是cusnum⽆效,因此不会有重复的数据。⽽且我们只要把数据全部导出即可,不关注数据的顺序,因此我们可以⽤union all来替换union。
修改后再次执⾏,这次只花费不到30分钟就把数据导出了,效率提升了28倍。如果数据量更⼤的话,这个效率提升会更明显。
总结
UNION ALL 要⽐UNION快很多,所以,如果可以确认合并的两个结果集中不包含重复数据且不需要排序时的话,那么就使⽤UNION ALL。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论