实体班一位学生最近要做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