原创地址: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