利用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

 

 

 

 

 

 

 

 

 

 


 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章