利用or改写union all

实体班一位学生最近要做SQL优化,发来一条SQL:


select t.flowmeterno,
        t.flowmetername,
        t.cardno,
        nvl("2020-04-08(m³)", 0) + nvl("2020-04-09(m³)", 0) +
        nvl("2020-04-10(m³)", 0) + nvl("2020-04-11(m³)", 0) +
        nvl("2020-04-12(m³)", 0) + nvl("2020-04-13(m³)", 0) +
        nvl("2020-04-14(m³)", 0) + nvl("2020-04-15(m³)", 0) total,
        "2020-04-08(m³)",
        "2020-04-09(m³)",
        "2020-04-10(m³)",
        "2020-04-11(m³)",
        "2020-04-12(m³)",
        "2020-04-13(m³)",
        "2020-04-14(m³)",
        "2020-04-15(m³)"
   from (select *
           from (select a.flowmeterno,
                        a.FLOWMETERNAME,
                        a.CARDNO,
                        a.ADDRESS,
                        b.ctime,
                        b.water
                   from tb_base_flowmeter a
                   left join test_01 b
                     on a.FLOWMETERNO = b.deviceno
                  where a.increase_id is not null
                    and a.state = 1
                    and a.increase_id not in
                        (select increase_id
                           from netplus_user.test_02 b
                          where b.update_type = '4'
                            and b.updtime between
                                to_date('2020-04-08', 'yyyy-MM-dd') and
                                to_date('2020-04-15', 'yyyy-MM-dd'))
                    and b.ctime between '2020-04-08' and '2020-04-15'
                 union all
                 select a.flowmeterno,
                        a.FLOWMETERNAME,
                        a.CARDNO,
                        a.ADDRESS,
                        b.ctime,
                        b.water
                   from tb_base_flowmeter a,
                        (select water, ctime, '' as deviceno
                           from test_01
                          where deviceno = '1612000780100001'
                            and ctime >= '2020-04-08'
                            and ctime <= '2020-04-14 10:00:08'
                         union all
                         select water, ctime, '' as deviceno
                           from test_01
                          where deviceno = '1612000204100001'
                            and ctime >= '2020-04-14 10:00:08'
                            and ctime <= '2020-04-15'
                         union all
                         select water, ctime, '' as deviceno
                           from test_01
                          where deviceno = '1612000495100001'
                            and ctime >= '2020-04-08'
                            and ctime <= '2020-04-08 09:40:13'
                         union all
                         select water, ctime, '' as deviceno
                           from test_01
                          where deviceno = '2002010198030002'
                            and ctime >= '2020-04-08 09:40:13'
                            and ctime <= '2020-04-15'
                         union all
                         select water, ctime, '' as deviceno
                           from test_01
                          where deviceno = '2012000121030002'
                            and ctime >= '2020-04-08'
                            and ctime <= '2020-04-14 11:26:50'
                         union all
                         select water, ctime, '' as deviceno
                           from test_01
                          where deviceno = '1812010179030002'
                            and ctime >= '2020-04-14 11:26:50'
                            and ctime <= '2020-04-15'
                         union all
                         select water, ctime, '' as deviceno
                           from test_01
                          where deviceno = '1611240030030002'
                            and ctime >= '2020-04-08'
                            and ctime <= '2020-04-13 08:59:25'
                         union all
                         select water, ctime, '' as deviceno
                           from test_01
                          where deviceno = '1912010013030002'
                            and ctime >= '2020-04-13 08:59:25'
                            and ctime <= '2020-04-15'
                         union all
                         select water, ctime, '' as deviceno
                           from test_01
                          where deviceno = '1610010157030002'
                            and ctime >= '2020-04-08'
                            and ctime <= '2020-04-10 11:00:43'
                         union all
                         select water, ctime, '' as deviceno
                           from test_01
                          where deviceno = '1711010043030002'
                            and ctime >= '2020-04-10 11:00:43'
                            and ctime <= '2020-04-15'
                         union all
                         select water, ctime, '' as deviceno
                           from test_01
                          where deviceno = '1907000216100001'
                            and ctime >= '2020-04-08'
                            and ctime <= '2020-04-13 14:42:36'
                         union all
                         select water, ctime, '' as deviceno
                           from test_01
                          where deviceno = '1610010275030002'
                            and ctime >= '2020-04-13 14:42:36'
                            and ctime <= '2020-04-15'
                         union all
                         select water, ctime, '' as deviceno
                           from test_01
                          where deviceno = '1612000530100001'
                            and ctime >= '2020-04-08'
                            and ctime <= '2020-04-14 09:23:08'
                         union all
                         select water, ctime, '' as deviceno
                           from test_01
                          where deviceno = '1709010053030002'
                            and ctime >= '2020-04-14 09:23:08'
                            and ctime <= '2020-04-15'
                         union all
                         select water, ctime, '' as deviceno
                           from test_01
                          where deviceno = '1907000501100001'
                            and ctime >= '2020-04-08'
                            and ctime <= '2020-04-14 13:44:49'
                         union all
                         select water, ctime, '' as deviceno
                           from test_01
                          where deviceno = '2003010050030002'
                            and ctime >= '2020-04-14 13:44:49'
                            and ctime <= '2020-04-15'
                         union all
                         select water, ctime, '' as deviceno
                           from test_01
                          where deviceno = '1905000801100001'
                            and ctime >= '2020-04-08'
                            and ctime <= '2020-04-14 09:57:20'
                         union all
                         select water, ctime, '' as deviceno
                           from test_01
                          where deviceno = '2003010033030002'
                            and ctime >= '2020-04-14 09:57:20'
                            and ctime <= '2020-04-15'
                         union all
                         select water, ctime, '' as deviceno
                           from test_01
                          where deviceno = '1702000829100001'
                            and ctime >= '2020-04-08'
                            and ctime <= '2020-04-14 13:37:47'
                         union all
                         select water, ctime, '' as deviceno
                           from test_01
                          where deviceno = '2003010150030002'
                            and ctime >= '2020-04-14 13:37:47'
                            and ctime <= '2020-04-15'
                         union all
                         select water, ctime, '' as deviceno
                           from test_01
                          where deviceno = '1612000601100001'
                            and ctime >= '2020-04-08'
                            and ctime <= '2020-04-14 09:58:48'
                         union all
                         select water, ctime, '' as deviceno
                           from test_01
                          where deviceno = '1612000259100001'
                            and ctime >= '2020-04-14 09:58:48'
                            and ctime <= '2020-04-15'
                         union all
                         select water, ctime, '' as deviceno
                           from test_01
                          where deviceno = '1702000841100001'
                            and ctime >= '2020-04-08'
                            and ctime <= '2020-04-10 15:44:42'
                         union all
                         select water, ctime, '' as deviceno
                           from test_01
                          where deviceno = '1612000547100001'
                            and ctime >= '2020-04-10 15:44:42'
                            and ctime <= '2020-04-15') b
                  where a.flowmeterno = b.deviceno)
         pivot(sum(water)
            for ctime in('2020-04-08' "2020-04-08(m³)",
                        '2020-04-09' "2020-04-09(m³)",
                        '2020-04-10' "2020-04-10(m³)",
                        '2020-04-11' "2020-04-11(m³)",
                        '2020-04-12' "2020-04-12(m³)",
                        '2020-04-13' "2020-04-13(m³)",
                        '2020-04-14' "2020-04-14(m³)",
                        '2020-04-15' "2020-04-15(m³)"))) t;

这条SQL要跑40多秒,让我优化一下,各位看官,请仔细看这条SQL

这条SQL中有很多UNION ALL,并且UNION ALL里面都是访问的test_01,截取其中一段代码

select water, ctime, '' as deviceno
  from test_01
 where deviceno = '1612000780100001'
   and ctime >= '2020-04-08'
   and ctime <= '2020-04-14 10:00:08'
union all
select water, ctime, '' as deviceno
  from test_01
 where deviceno = '1612000204100001'
   and ctime >= '2020-04-14 10:00:08'
   and ctime <= '2020-04-15'

我也是佩服这位开发人员,写这么多UNION ALL干嘛,于是建议把SQL改写为or

select water, ctime, '' as deviceno
  from test_01
where  
( deviceno = '1612000780100001'
   and ctime >= '2020-04-08'
   and ctime <= '2020-04-14 10:00:08')
   or
(deviceno = '1612000204100001'
   and ctime >= '2020-04-14 10:00:08'
   and ctime <= '2020-04-15')

这样改写之后SQL可以秒出

想学习SQL优化吗?去京东买本 《SQL优化核心思想》吧  https://item.jd.com/12344162.html

或者找我报个单独辅导的SQL优化培训 嘿嘿  微信: 692162374

扫描二维码关注公众号,回复: 11228407 查看本文章


 

猜你喜欢

转载自blog.csdn.net/robinson1988/article/details/105587589
今日推荐