我有一个包含函数和过程的包,这些函数和过程都具有查找静态表以获取代码值的重复逻辑。我不确定实现这一目标的最佳做法是什么。Oracle会在第一次调用后缓存表吗?我只需要把公共查询放到一个函数中,然后从其他函数/过程调用它吗?这是否意味着每次运行函数/过程时,都会再次运行select?有没有一种缓存表的方法?任何建议和想法将不胜感激。
vd2z7a6w1#
您可以在函数中使用RESULT_CACHE子句。这将缓存函数结果-而不是表-但最终结果应该是相同的。docs在这里
RESULT_CACHE
ipakzgxi2#
这些查找会给您的流程增加多少时间?如果你的音量很低,这可能不是一个值得解决的问题。1.通过唯一键的单值查找将使用缓冲的单块读取,这意味着块几乎都将最终在数据库缓冲区缓存中,因此只要您的查找表的大小不是数百GB并且超过缓存容量(不太可能),当它启动时几乎不会涉及任何I/O。1.查询SQL将被预先解析(假设你使用的是绑定变量,在PL/SQL中,除非你使用的是动态SQL,这在这个场景中是值得怀疑的),所以每次查询的CPU开销非常小。我们说的是毫秒。1.如果扩展索引,使其不仅覆盖惟一键,还覆盖正在检索的列,则可以完全避免从表中查看块缓冲区。在高频率下,这可以显著降低CPU开销。1.您可以使用结果缓存。只要确保表没有经常被修改,因为如果无效太频繁,结果缓存可能会导致数据库出现问题。然而,对于1:1查找(一个源表行对应一个行结果),结果缓存不是一种非常有效的机制。它更适合于绕过昂贵的聚合。1.对于小的查找表,您可以将名称-值对预加载到PL/SQL关联数组中,并在代码中查找关联数组中的值,而不是使用SQL。这是非常快的。1.对于较大的查找,但具有显著的偏差(许多值未使用,一些值使用得更频繁),您可以使用SQL进行查找,但自己将结果缓存在关联数组中。然后,每个查找将首先检查数组,并且仅在查找SQL尚未在数组中时才执行查找SQL。永远不需要的值将不会被加载。只要确保您有足够的PGA来容纳阵列的最终大小即可。
2条答案
按热度按时间vd2z7a6w1#
您可以在函数中使用
RESULT_CACHE
子句。这将缓存函数结果-而不是表-但最终结果应该是相同的。docs在这里ipakzgxi2#
这些查找会给您的流程增加多少时间?如果你的音量很低,这可能不是一个值得解决的问题。
1.通过唯一键的单值查找将使用缓冲的单块读取,这意味着块几乎都将最终在数据库缓冲区缓存中,因此只要您的查找表的大小不是数百GB并且超过缓存容量(不太可能),当它启动时几乎不会涉及任何I/O。
1.查询SQL将被预先解析(假设你使用的是绑定变量,在PL/SQL中,除非你使用的是动态SQL,这在这个场景中是值得怀疑的),所以每次查询的CPU开销非常小。我们说的是毫秒。
1.如果扩展索引,使其不仅覆盖惟一键,还覆盖正在检索的列,则可以完全避免从表中查看块缓冲区。在高频率下,这可以显著降低CPU开销。
1.您可以使用结果缓存。只要确保表没有经常被修改,因为如果无效太频繁,结果缓存可能会导致数据库出现问题。然而,对于1:1查找(一个源表行对应一个行结果),结果缓存不是一种非常有效的机制。它更适合于绕过昂贵的聚合。
1.对于小的查找表,您可以将名称-值对预加载到PL/SQL关联数组中,并在代码中查找关联数组中的值,而不是使用SQL。这是非常快的。
1.对于较大的查找,但具有显著的偏差(许多值未使用,一些值使用得更频繁),您可以使用SQL进行查找,但自己将结果缓存在关联数组中。然后,每个查找将首先检查数组,并且仅在查找SQL尚未在数组中时才执行查找SQL。永远不需要的值将不会被加载。只要确保您有足够的PGA来容纳阵列的最终大小即可。