0

我有一个关于如何在库缓存中处理通过“立即执行”执行的查询的问题(我们使用 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 说这是你的错”。

4

2 回答 2

0

getfield 和 searchfield 的不同组合的数量应该决定有多少“副本”。我谨慎地使用“副本”这个词,因为 Oracke 会将每个变体视为不同的。由于您为 searchvalue 使用绑定变量,因此无论您为此拥有多少值都不会添加到查询计数中。

简而言之,看起来您的代码还可以。

连接数不应增加硬解析。

要求 AWR 报告以准确了解 SGA 中有多少此类查询,以及触发了多少硬解析。

于 2015-12-05T18:24:31.303 回答
0

我不同意连接数不会增加发布代码的硬解析计数,因为我知道的最后一个动态 SQL 不能在会话之间共享。由于生成的 SQL 使用绑定变量,它应该生成会话可重用的语句,但它不能在用户会话之间共享。作为一般规则,动态 SQL 应该只用于不经常执行的语句。您可能需要参考以下内容: - - 为性能和可扩展性设计应用程序 Oracle 白皮书 2005 年 7 月 https://www.oracle.com/technetwork/database/performance/designing-applications-for-performa-131870.pdf - -

enter code here
于 2019-07-02T14:34:07.037 回答