嗨,我有这五个select语句,我使用union来组合它们。 但是我的问题是执行需要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';
希望我说清楚。 谢谢你。
答案 0 :(得分:0)
也许。
UNION
将返回 unique 行;如果可能,请将其更改为UNION ALL
2020-03-01
没有用;您认为您将截断什么? 而不是将字符串转换为日期(使用to_date
)和(先前的注释)将其截断,而使用日期文字(始终为yyyy-mm-dd
格式),例如
where date_time >= date '2020-03-01'
索引date_time
列可能会有所帮助(以及remarks
);看看解释计划怎么说
答案 1 :(得分:0)
首先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(*)
,因为您只想计算行数;由于您的REMARKS
子句,WHERE
永远不能为null。但是我猜想优化器会看到这一点,而您不会提高速度,只会提高可读性。
两个注意事项:
DATE '2020-03-31'
。使用这些代替字符串操作。"COUNT"
是保留的SQL字。我不会将它用作列名。