Oracle查询优化帮助(涉及TRUNC)

时间:2012-11-21 16:53:30

标签: oracle date query-optimization

这是查询。 closed_ts是一个时间戳列。我想要做的是,找出今天,本月,今年和本周有多少人“关闭”了。有更好的方法吗?

select table_id,
  case
    when trunc(closed_ts) = trunc(SYSDATE, 'DD') then 1
    else 0
  end as day_count,
  case
    when trunc(closed_ts) >= trunc(SYSDATE, 'MM') then 1
    else 0
  end as month_count,
 case
   when trunc(closed_ts) >= trunc(sysdate, 'YYYY') then 1
   else 0
 end as year_count,
 case
   when trunc(closed_ts) >= TRUNC(sysdate, 'IW') then 1
   else 0
 end as week_count
from myTable

2 个答案:

答案 0 :(得分:0)

好像你想用table_id围绕每个case语句和group聚合值和sum(),但是因为你询问了查询优化......

如果有一个关于closed_ts的索引,你将无法使用它,因为你正在截断它。截断closed_ts日期是不必要的,因为您要检查它是否严格大于日,周,月,年,因此此查询肯定会导致全表扫描。

我可能会在没有trunc的情况下重写它是否有关于closed_ts的索引:

select table_id
      ,sum(case when closed_ts >= trunc(sysdate) then 1 else 0 end) as day_count
      ,sum(case when closed_ts >= trunc(sysdate,'MM') then 1 else 0 end) as month_count
      ,sum(case when closed_ts >= trunc(sysdate,'YYYY') then 1 else 0 end) as year_count
      ,sum(case when closed_ts >= trunc(sysdate,'IW') then 1 else 0 end) as week_count
 from myTable
group by table_id

btw:table_id听起来像是主键或代理键 - 你确定要在结果中使用它吗?

答案 1 :(得分:0)

在(closed_ts,table_id)上弹出索引,并在closed_ts上应用谓词,如下所示......

 select
   table_id,
   sum(case when closed_ts >= trunc(SYSDATE,'DD'  ) then 1 end) day_count,
   sum(case when closed_ts >= trunc(SYSDATE,'MM'  ) then 1 end) month_count,
   sum(case when closed_ts >= trunc(SYSDATE,'YYYY') then 1 end) year_count,
   sum(case when closed_ts >= trunc(SYSDATE,'IW'  ) then 1 end) week_count,
 from
   myTable
 where
   closed_ts >= least(trunc(SYSDATE,'YYYY'),trunc(SYSDATE,'IW'))
 group by
   table_id

如用户1842757所述,在closed_ts上丢失截断。您也可以在案例陈述中丢失ELSE 0