sql的子查询超级慢-子查询酿的祸

原创地址:https://blog.csdn.net/QQ826688096/article/details/89351317


今天碰到一个问题,就是子查询导致查询效率特别低,到了31秒了。特此先记录一下,后期修改。

1,原始子查询写法的sql

前提条件:sz_jsxxb这个表是教师表,大约有5万多条数据

select 
	sys_guid(),
	(select count(zgh)as nanrs from (select zgh,xydm from sz_jsxxb where xb='1') s where t.yxdm=s.xydm) nanrs,
	(select count(zgh)as nanrs from (select zgh,xydm from sz_jsxxb where xb='2') s where t.yxdm=s.xydm) nvrs,
	(select count(zgh)as nanrs from (select zgh,xydm from sz_jsxxb where xb!='1'and xb!='2') s where t.yxdm=s.xydm)nan_nv_rs,
	t.yxmc
from dm_yxb t

上面这个sql执行效率是31秒。
**原因:**子查询导致的,这样的sql,导致会查询教师表sz_jsxxb 的次数是:主表dm_yxb的count数的次数,效率肯定是奇慢无比了。

2,修改成左连接查询(但是出现数据重复重大BUG)

然后,将子查询修改成左连接后:

select 
	sys_guid(),
	count(jsb1.zgh) nanrs,
	count(jsb2.zgh) nvrs,
	count(jsb3.zgh) nan_nv_rs,
	t.yxmc
from dm_yxb t
left join (select zgh,xb,xydm from sz_jsxxb where xb='1' and xydm is not null) jsb1 on t.yxdm=jsb1.xydm
left join (select zgh,xb,xydm from sz_jsxxb where xb='2' and xydm is not null) jsb2 on t.yxdm=jsb2.xydm 
left join (select zgh,xb,xydm from sz_jsxxb where xb!='1' and xb!='2' and xydm is not null) jsb3 on t.yxdm=jsb3.xydm
group by t.yxmc

这是初步想法的实现,效果还可以,从31秒一下到了1.09秒,把我高兴了一把。哐哐哐的兴奋一顿后,发现是有个问题,就是查询的结果不如人意,有不会报错的严重数据错误,如下图:
在这里插入图片描述
查询出的结果就是如上面表所示,“NANRS” , “NVRS” 的内容是一样的。这种问题,看着不报错,事实上,这种问题最大。
这里这个问题,导致问题的原因我暂时没有找到,但是看着没有毛病,就是数据不对。希望大神给指点。

3,把要查询的结果直接在左连接里面查询出来,主查询直接取结果值

然后,我再次修改,将查询count数的语法搬迁到 left 里面了,然后,在查询的时候,直接去 left 里面的count数就可以了。

select 
	sys_guid(),
	x.rs nanrs,
	y.rs nvrs,
	z.rs nan_nv_rs,
	t.yxmc
from dm_yxb t
left join (select count(zgh) rs,xydm from sz_jsxxb where xb='1' and xydm is not null group by xydm) x on t.yxdm=x.xydm
left join (select count(zgh) rs,xydm from sz_jsxxb where xb='2' and xydm is not null group by xydm) y on t.yxdm=y.xydm 
left join (select count(zgh) rs,xydm from sz_jsxxb where xb!='1' and xb!='2' and xydm is not null group by xydm) z on t.yxdm=z.xydm

上面这个sql才是最终的正确的结果,时间也是1.09秒,挺如人意了。

附录:探讨问题:

如果你是大牛,希望你帮忙解决下上面我提出的疑惑,一块探讨啊!

后补:

比较好的解决办法是评论区里那个兄弟写的那样,但是效率依旧不如左连接快

select sum(  case when xb='1' then 1 else 0 end  ) as nanrs,
       sum(   case when xb='2' then 2 else 0 end   ) as nvrs,
       sum(   case when xb!='1' and  xb!='1' then 1 else 0 end   ) as nan_nv_rs,
       yxb.yxmc
from sz_jsxxb t
left join dm_yxb yxb on yxb.yxdm=t.xydm
where t.xydm is not null
group by t.xydm,yxb.yxmc
  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值