to_date在where子句中执行了多少次?

时间:2017-03-22 19:24:00

标签: sql oracle

在以下查询中,to_date函数是多次执行还是只执行一次?这个查询运行时间很长,我试图找到解决方法而不要求添加索引。

select edi_stat_rsn_cd
, TSET_ID
, count(*) as count
from comt_po_msg
where TSET_ID in ('PSH','ORD','850','870')
and trunc(crt_ts) = to_date('03-06-2017','mm-dd-yyyy') --here
and LOC_TYP_CD in ('BOSS','STH')
group by edi_stat_rsn_cd, TSET_ID;

3 个答案:

答案 0 :(得分:1)

合理的优化器应该只对常量调用一次确定性函数。但为什么要这么麻烦?相反,请使用date关键字来包含日期常量:

where TSET_ID in ('PSH', 'ORD', '850', '870') and
      trunc(crt_ts) = date '2017-03-06' and
      LOC_TYP_CD in ('BOSS', 'STH')

这具有允许标准日期格式的额外优势。

使用trunc(crt_ts)可以阻止优化器使用索引 - 这比调用to_date()要大得多。我建议:

where TSET_ID in ('PSH', 'ORD', '850', '870') and
      crt_ts >= date '2017-03-06' and
      crt_ts < '2017-03-07' and
      LOC_TYP_CD in ('BOSS', 'STH')

答案 1 :(得分:0)

尝试以下查询。这将避免每行的TRUNC()函数,

SELECT EDI_STAT_RSN_CD
    , TSET_ID
    , COUNT(*) AS COUNT
FROM COMT_PO_MSG
WHERE TSET_ID IN ('PSH','ORD','850','870')
    --AND TRUNC(CRT_TS) = TO_DATE('03-06-2017','MM-DD-YYYY') --HERE
    AND TO_CHAR(CRT_TS, 'MM-DD-YYYY') = '03-06-2017'
    AND LOC_TYP_CD IN ('BOSS','STH')
GROUP BY EDI_STAT_RSN_CD
    , TSET_ID;

答案 2 :(得分:0)

如前所述,它应该被视为静态,因为您使用静态值to_date('03-06-2017','mm-dd-yyyy')并且您的to_date()函数不依赖于列值(或)未根据每个记录值进行评估< / p>