嗨,我有这五个select语句,我使用并集来组合它们。但我的问题是执行需要25秒,有没有办法让这种执行速度更快?
Select Case when sum(COUNT)is null then 0 end as count,'Exeed45' as tittle from VW_BREAK_TIME_EXCEEDING45
where date_time >= trunc(To_date('2020-03-01','YYYY-MM-DD')) and date_time <= trunc(to_date('2020-03-31','YYYY-MM-DD'))
union
Select Case when sum(CNT) is null then 0 end as count,'Double' as tittle from VW_BREAK_TIME_DOUBLEBREAK
where date_time >= trunc(To_date('2020-03-01','YYYY-MM-DD')) and date_time <= trunc(to_date('2020-03-31','YYYY-MM-DD'))
union
Select sum(COUNT)as count,'Frequent' as tittle from VW_BREAK_TIME_FREQUENTBREAK
where date_time >= trunc(To_date('2020-03-01','YYYY-MM-DD')) and date_time < =trunc(to_date('2020-03-31','YYYY-MM-DD'))
union
Select Count(REMARKS)as count,'LateProd' as tittle from VW_BREAK_TIME_PROD_TIMEIN
where date_time >= trunc(To_date('2020-03-01','YYYY-MM-DD')) and date_time <= trunc(to_date('2020-03-31','YYYY-MM-DD'))
and REMARKS = 'LATE'
union
Select Count(REMARKS)as count,'EarlyOut' as tittle from VW_BREAK_TIME_PROD_TIMEOUT
where date_time >= trunc(To_date('2020-03-01','YYYY-MM-DD')) and date_time <= trunc(to_date('2020-03-31','YYYY-MM-DD'))
and REMARKS = 'Early Out';
希望我说清楚。提前谢谢。
首先,UNION
是一个代价高昂的操作,不仅要将两个结果粘合在一起,还要查找要删除的任何重复项。您需要UNION ALL
,它只完成粘合部分,因为您的查询不会给出重复项(因为tittle
不同(。
然后,date_time
列上应该有索引,再加上每个表的汇总列:
create index idx1 on vw_break_time_exceeding45 (date_time, "COUNT");
create index idx2 on VW_BREAK_TIME_DOUBLEBREAK (date_time, cnt);
create index idx3 on VW_BREAK_TIME_FREQUENTBREAK (date_time, "COUNT");
create index idx4 on VW_BREAK_TIME_PROD_TIMEIN (date_time, remarks);
create index idx5 on VW_BREAK_TIME_PROD_TIMEOUT (date_time, remarks);
对于remarks
比date_time
更有选择性的情况,我还要添加以下索引。(您可以随时查看查询的解释计划,并删除未使用的索引。(
create index idx6 on VW_BREAK_TIME_PROD_TIMEIN (remarks, date_time);
create index idx7 on VW_BREAK_TIME_PROD_TIMEOUT (remarks, date_time);
您不应该使用Count(REMARKS)
,而是COUNT(*)
,因为您只想计算行数;由于您的WHERE
子句,REMARKS
永远不能为null。但我猜优化器能看穿这一点,你不会获得速度,只有可读性。
两个旁注:
- 日期文字如下所示:
DATE '2020-03-31'
。使用这些而不是字符串操作 "COUNT"
是一个保留的SQL字。我不会用它作为列名
也许吧。
UNION
将返回唯一行;如果可能,请将其更改为UNION ALL
- 截断例如CCD_ 15是无用的;你认为你会截断什么
-
不要将字符串转换为日期(使用
to_date
(并(前一句话(截断它,而是使用日期文字(始终为yyyy-mm-dd
格式(,例如where date_time >= date '2020-03-01'
-
索引
date_time
列可能会有所帮助(与remarks
一样(;看看是怎么解释的 - 你收集了那些表格的统计数据吗?如果没有,就去做