我正在尝试优化我在where子句中使用function()调用的查询。
function()只是改变日期的时区。
当我将该函数作为SELECT的一部分调用时,它执行速度非常快(对于数十万行的表,<0.09秒)
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
希望我能很好地解释这个问题。
答案 0 :(得分:0)
WHERE子句中的函数调用是一件坏事。问题是可以为表中的每一行调用该函数,该函数可能比所选集多得多。这可能是一个真正的性能杀手(不要问我怎么知道:-)。在SELECT列表中具有函数调用的第一个版本中,只有在选择了行并将其添加到结果集时才会调用该函数 - 在第二个版本中,可以为表中的每一行调用该函数。此外,根据您使用的Oracle版本,从SQL调用用户函数可能会产生很大的开销,但我认为自10g以来版本中已经大大消除了这种惩罚。
祝你好运。
分享并享受。
答案 1 :(得分:0)
在WHERE
子句中使用函数至少存在四个潜在问题:
DETERMINISTIC
,PARALLEL_ENABLE
,函数结果缓存,在纯SQL中定义逻辑,或用12c定义SQL中的函数。ASSOCIATE STATISTICS
可以向优化器提供有关函数成本和基数的一些信息。如果没有更多信息,例如解释计划,很难知道此查询的具体问题是什么。