在 where 子句中使用函数的 Oracle 性能

2024-01-07

在存储过程(有一个名为 'paramDate' 的日期参数)中,我有一个像这样的查询

select id, name
from customer
where period_aded = to_char(paramDate,'mm/yyyy')

Oracle会将每行的paramDate转换为字符串吗?

我确信 Oracle 不会,但有人告诉我 Oracle 会。 事实上,我认为如果函数的参数是约束(在查询中没有得到字段或计算值),结果应该总是相同的,这就是为什么 Oracle 应该只执行一次这种转换。 然后我意识到我有时会在多个函数中执行 DML 语句,这可能会导致结果值发生变化,即使它不会针对每一行发生变化。

这应该意味着我应该在将这些值添加到查询之前对其进行转换。

无论如何,也许众所周知的“已知函数”(内置)会被评估一次,甚至我的函数也会被评估一次。

无论如何,再一次...

Oracle 会执行一次 to_char 还是会为每一行执行一次?

感谢您的回答


我认为通常情况并非如此,因为它会阻止使用索引。

至少对于内置函数,Oracle 应该能够弄清楚它只能对其进行一次评估。 (对于用户定义的函数,请参见下文)。

这是使用索引的情况(并且不会对每一行评估该函数):

SQL> select id from tbl_table where id > to_char(sysdate, 'YYYY');

--------------------------------------------------------------------------------
| Id  | Operation        | Name        | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------
|   0 | SELECT STATEMENT |             |    35 |   140 |     1   (0)| 00:00:01 |
|*  1 |  INDEX RANGE SCAN| SYS_C004274 |    35 |   140 |     1   (0)| 00:00:01 |
--------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

1 - access("ID">TO_NUMBER(TO_CHAR(SYSDATE@!,'YYYY')))

对于用户定义的函数,请查看此article http://www.inside-oracle-apex.com/caution-when-using-plsql-functions-in-sql-statement/。它提到了两种方法来确保 你的函数只被调用一次:

  1. 从 Oracle 10.2 开始,您可以将函数定义为 DETERMINISTIC。

  2. 在旧版本上,您可以将其重新表述为使用“标量子查询缓存”:

    选择计数(*) 来自员工 WHERE SALARY = (从 DUAL 中选择 getValue(1));

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 where 子句中使用函数的 Oracle 性能 的相关文章

随机推荐