我有一个关于查询如何通过在库缓存中处理"execute immediate"(我们使用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个连接,但每个连接都使用相同的数据库登录名。
现在,我们还假设搜索值在一个循环中更改了b次。
问题1:当计算将在库高速缓存中保留多少sql副本时,我们可以忽略searchvalue可能具有的不同值吗(b),因为该值作为参数发送以立即执行?
问题2:循环是否会导致对查询进行x次硬解析(查询将在库缓存中创建x次),或者Oracle是否可以重用该查询?(为了简单起见,我们假设这个问题中的所有调用的搜索值都是相同的)
问题3:y(在一个连接的生存期内从odbc调用存储过程的次数)还要乘以库缓存中保存的查询副本数量?
问题4:是否执行z(具有相同数据库登录的同时连接数)乘以库缓存中保存的查询副本数量?
主要问题:我在这里应该期待什么样的行为?行为是否可配置?这个问题的原因是,我们已经有4年的代码生产了,现在我们的一位客户回复我们说:"这个查询填满了我们的整个SGA,Oracle说这是你的错"。
getfield和searchfield的不同组合的数量应该决定有多少"副本"。我谨慎地使用"副本"一词,因为Oracke会将每个变体视为不同的。由于您使用的是searchvalue的绑定变量,因此无论您有多少值,都不会添加到查询计数中。
简而言之,看起来你的代码还可以
连接数不应增加硬解析。
要求提供AWR报告,以查看SGA中有多少查询,以及触发了多少硬解析。
我不同意连接数量不会增加发布代码的硬解析计数,因为我所知道的最后一个动态SQL不能在会话之间共享。由于生成的SQL使用绑定变量,它应该由会话生成一个可重用的语句,但它不能在用户会话之间共享。一般来说,动态SQL应该只用于不经常执行的语句。您可能需要参考以下内容:--为性能和可扩展性设计应用程序Oracle白皮书2005年7月https://www.oracle.com/technetwork/database/performance/designing-applications-for-performa-131870.pdf--
enter code here