我有一个关于如何在库缓存中处理通过“execute immediate”执行的查询的问题(我们使用Oracle11)。
假设我有一个这样的函数:
FUNCTION get_meta_map_value (
getfield IN VARCHAR2,
searchfield IN VARCHAR2,
searchvalue IN VARCHAR2
) RETURN VARCHAR2 IS
v_outvalue VARCHAR2(32767);
sql_stmt VARCHAR2(2000) := 'SELECT '||getfield||' FROM field_mapping, metadata '||
'WHERE field_mapping.metadataid = metadata.metadataid AND rownum = 1 AND '||searchfield||' = :1';
BEGIN
EXECUTE IMMEDIATE sql_stmt INTO v_outvalue USING searchvalue;
...
getfield和searchfield在一个安装中总是相同的(但在另一个安装中有其他值,这就是我们使用动态sql的原因),所以这就给我们留下了一个只在search值(这是一个参数)上有所不同的sql。此函数在一个循环中调用,该循环从另一个存储过程中执行x次。存储过程在连接生存期内通过ODBC连接执行y次。有z个连接,但每个连接都使用相同的数据库登录。
现在,让我们还假设搜索值在一个循环期间更改了b次。
问题1:在计算库缓存中将保留多少个sql副本时,我们可以忽略搜索值可以具有的不同值(b),因为该值是作为参数发送以执行immediate的吗?
问题2:循环是否会导致查询硬解析x次(查询将在库缓存中创建x次),或者Oracle可以重用该查询吗?(为了简单起见,我们假设此问题中的所有调用的搜索值都相同)
问题3: y(在一个连接的生命周期内从odbc调用存储过程的次数)是否也会使库缓存中保存的查询副本数量成倍增加?
问题4: z(具有相同数据库登录的同时连接的数量)是否乘以库缓存中保存的查询副本的数量?
主要问题:在这里我应该期待什么样的行为?行为是可配置的吗?这个问题的原因是我们已经有这个代码4年了,现在我们的一个客户回复我们说“这个查询填满了我们的整个SGA,Oracle说这是你的错”。
发布于 2015-12-05 18:24:31
getfield和searchfield的不同组合的数量应该决定将有多少个“副本”。我谨慎地使用“副本”这个词,因为Oracke会将每个变体视为不同的变体。由于您对searchvalue使用了绑定变量,因此您拥有的许多值都不会添加到查询计数中。
简而言之,你的代码看起来没问题。
连接的数量不应增加硬解析。
请求AWR报告,以查看SGA中到底有多少这样的查询,以及触发了多少硬解析。
发布于 2019-07-02 14:34:07
我不同意连接数量不会增加发布代码的硬解析计数的说法,因为我所知道的最后一个动态SQL不能在会话之间共享。由于生成的SQL使用绑定变量,因此它应该由会话生成一个可重用的语句,但它不能在用户会话之间共享。一般来说,动态SQL应该只用于不经常执行的语句。您可以参考以下内容:-- Designing applications for performance and scalability An Oracle白皮书2005年7月https://www.oracle.com/technetwork/database/performance/designing-applications-for-performa-131870.pdf --
enter code here
https://stackoverflow.com/questions/34015325
复制相似问题