【发布时间】:2014-05-17 04:03:59
【问题描述】:
我正在尝试优化我在 where 子句中使用 function() 调用的查询。
function() 只是更改日期的时区。
当我将函数作为 SELECT 的一部分调用时,它的执行速度非常快(对于数十万行的表来说,
select
id,
fn_change_timezone (date_time, 'UTC', 'US/Central') AS tz_date_time,
value
from a_table_view
where id = 'keyvalue'
and date_time = to_date('01-10-2014','mm-dd-yyyy')
但是,这个版本“永远”运行[意味着我在无数分钟后停止它]
select id, date_time, value
from a_table_view
where id = 'keyvalue'
and fn_change_timezone (date_time, 'UTC', 'US/Central') = to_date('01-10-2014','mm-dd-yyyy')
(我知道我必须更改被比较的日期,这只是示例)
所以我的问题有两个:
如果函数在 where 子句之外如此之快,为什么它比使用 TRUNC() 或其他函数慢得多(显然 trunc() 不像我的函数那样进行表查找 - 但仍然是函数在where子句之外非常非常快)
在 where 子句之外有哪些替代方法可以完成此任务?
我尝试了这个作为替代方案,但似乎并没有更好,它仍然运行,直到我停止查询:
select
tz.date_time,
v.id,
v.value
from
(select
fn_change_timezone(to_date('01/10/2014-00:00:00', 'mm/dd/yyyy-hh24:mi:ss'), 'UTC', 'US/Central') as date_time
from dual
) tz
inner join
(
select
id,
fn_change_timezone (date_time, 'UTC', 'US/Central') AS v_date_time,
value
from a_table_view
where id = 'keyvalue'
) v ON
v.tz_date_time = tz.date_time
希望我能很好地解释这个问题。
【问题讨论】:
-
您的函数是作为“不变量”还是“常量”函数创建的?这告诉优化器不需要为每组相同的参数重新调用函数。
-
我不理解那些与 Oracle 函数相关的术语。当我搜索时,Google 没有帮助。
-
对不起,我的错误,你想看看“确定性函数”。 dba-oracle.com/plsql/t_plsql_deterministic.htm
-
如果我理解正确 - 该函数不是用 DETERMINISTIC 关键字定义的,并且它总是会根据相同的输入值返回相同的值。它只是做一个表查找,并执行一个 from_tz() 和一些 cast()'ing
-
你能把函数重新定义为 DETERMINISTIC 吗?如果是这样,那应该对优化器有所帮助。此外,如果函数在幕后进行表查找,这也会使事情变慢。
标签: oracle function plsql query-optimization where-clause