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,包括它与基于函数的索引等的关系。
【讨论】:
是的,有两个缓存指令:DETERMINISTIC
和 CACHE RESULTS
。第一个仅是语句级别。
@ibre5041 - 是的,文档中还有更多指向结果缓存函数的链接,但这似乎有点离题了。
所以我上面描述的函数可以被标记为确定性,而不会在生产环境中出现一些奇怪的内存错误?当然...如果该函数确实是,则必须标记为 DETERMINISTICT:)
@Mistre83 - 我想,如果它可能使查询使用更少的临时内存的话。不过,它不会对单个查询之外的内存产生任何影响。
@Mistre83 这取决于您使用它的地方。恕我直言,如果您在连接多个表的查询中的 WHERE 子句中使用它,您应该标记它。以上是关于Oracle DETERMINISTIC HINT 开销的主要内容,如果未能解决你的问题,请参考以下文章