联合选择需要很长时间才能执行



嗨,我有这五个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);

对于remarksdate_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。但我猜优化器能看穿这一点,你不会获得速度,只有可读性。

两个旁注:

  1. 日期文字如下所示:DATE '2020-03-31'。使用这些而不是字符串操作
  2. "COUNT"是一个保留的SQL字。我不会用它作为列名

也许吧。

  • UNION将返回唯一行;如果可能,请将其更改为UNION ALL
  • 截断例如CCD_ 15是无用的;你认为你会截断什么
  • 不要将字符串转换为日期(使用to_date(并(前一句话(截断它,而是使用日期文字(始终为yyyy-mm-dd格式(,例如

    where date_time >= date '2020-03-01'
    
  • 索引date_time列可能会有所帮助(与remarks一样(;看看是怎么解释的

  • 你收集了那些表格的统计数据吗?如果没有,就去做

最新更新