Oracle DETERMINISTIC HINT 开销

Posted

技术标签:

【中文标题】Oracle DETERMINISTIC HINT 开销【英文标题】:Oracle DETERMINISTIC HINT Overhead 【发布时间】:2015-02-19 12:23:16 【问题描述】:

DETERMINISTIC HIT(如 Oracle 所说)用于缓存函数的结果(如果它可以是确定性的),但这种好处的开销是多少?

我会尝试更好地解释这一点:

CREATE OR REPLACE FUNCTION betwnstr (
   string_in   IN   VARCHAR2
 , start_in    IN   INTEGER
 , end_in      IN   INTEGER
)
   RETURN VARCHAR2 DETERMINISTIC
IS
BEGIN
   RETURN (SUBSTR (string_in, start_in, end_in - start_in + 1));
END;
/

这个简单的函数从给定字符串的 BEGIN 和 END 索引中提取字符。

现在我将开始在不同的表中使用此函数作为 SELECT 结果(其他函数、过程、包等),Oracle 将开始缓存来自同一输入的所有结果。

当然,在函数声明上添加一个简单的世界是一个很好的结果,但是大量使用它的副作用是什么?例如,如果使用不同的输入调用此函数百万次?

例如,我可以有许多其他功能作为 DETERMINISTICT:

一个 DETERMINISTIC 函数,用于计算两个给定日期的差值(以天为单位)

ecc

【问题讨论】:

我认为为确定性函数完成的“缓存”只发生在单个 SQL 执行中。如果它是确定性的,则不会为相同的输入调用两次。但该“缓存”不会用于下一个使用该函数的查询。 主要好处是当您在SELECT 语句的WHERE 子句中使用此功能时。 Oracle 优化器通常无法预测调用 PL/SQL 函数的成本。因此,当您使用 PL/SQL 函数来过滤 PL/SQL 函数调用的开销时,可能会很重要。此外,函数索引只能用于确定性函数。 【参考方案1】:

documentation says:

确定性

告诉优化器该函数在使用相同参数值调用时返回相同的值(如果不是这样,则指定 DETERMINISTIC 会导致不可预测的结果)。如果之前使用相同的参数值调用了该函数,则优化器可以使用之前的结果而不是再次调用该函数。

优化器可以使用之前的结果,但不能使用;这只是断言,如果它需要为相同的参数值多次调用它——通常在一个查询中——它可以选择只调用一次,因为你被保证它总是会得到相同的结果。这并不一定意味着函数结果可以缓存在查询之间的某个地方,尽管它们可能会被其他机制缓存(我认为)。

当 Oracle 缓存内容时,它会管理缓存大小以保持在可用内存范围内,并优化可用于各种功能的内存。基本上,假设您使用得当,您不必担心使函数具有确定性的副作用。

还有更多documentation here,包括它与基于函数的索引等的关系。

【讨论】:

是的,有两个缓存指令:DETERMINISTICCACHE RESULTS。第一个仅是语句级别。 @ibre5041 - 是的,文档中还有更多指向结果缓存函数的链接,但这似乎有点离题了。 所以我上面描述的函数可以被标记为确定性,而不会在生产环境中出现一些奇怪的内存错误?当然...如果该函数确实是,则必须标记为 DETERMINISTICT:) @Mistre83 - 我想,如果它可能使查询使用更少的临时内存的话。不过,它不会对单个查询之外的内存产生任何影响。 @Mistre83 这取决于您使用它的地方。恕我直言,如果您在连接多个表的查询中的 WHERE 子句中使用它,您应该标记它。

以上是关于Oracle DETERMINISTIC HINT 开销的主要内容,如果未能解决你的问题,请参考以下文章

oracle 的hint有啥用

Oracle中常见的Hint

Oracle Hint 用法

Oracle中Hint被忽略的几种常见情形

Oracle中Hint被忽略的几种常见情形

oracle 初试 hint