我有一个关于如何在库缓存中处理通过“立即执行”执行的查询的问题(我们使用 Oracle 11)。
假设我有这样的功能:
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 的原因)所以这给我们留下了一个仅在 searchvalue (这是一个参数)方面不同的 sql。此函数在执行 x 次的循环中从另一个存储过程内部调用。存储过程在连接生命周期内通过 ODBC 连接执行 y 次。并且有 z 个连接,但每个连接都使用相同的数据库登录。
现在让我们也假设 searchvalue 在一个循环中改变了 b 次。
问题 1:在计算库缓存中将保留多少个 sql 副本时,我们是否可以忽略 searchvalue 可以具有的不同值(b),因为该值作为参数发送以立即执行?
问题2:循环会导致查询x次硬解析(查询将在库缓存中创建x次),还是Oracle可以重用查询?(为了简单起见,我们假设这里问题中所有调用的搜索值都是相同的)
问题 3:y(在一个连接的生命周期内从 odbc 调用存储过程的次数)是否也会乘以保存在库缓存中的查询副本的数量?
问题 4:z(具有相同 db 登录的同时连接数)是否乘以保存在库缓存中的查询副本数量?
主要问题:我应该在这里期待什么行为?行为是否可配置?出现这个问题的原因是,我们的代码已经生产了 4 年,现在我们的一位客户回复我们说“这个查询填满了我们的整个 SGA,而 Oracle 说这是你的错”。