2011-06-01 49 views
6

我注意到parse_calls等于我们的Oracle 11g数据库中的执行次数。在Oracle中减少分析调用

select parse_calls, executions 
from v$sql order by parse_calls desc; 

运行上述查询得出以下结果。

"PARSE_CALLS" "EXECUTIONS" 
    87480  87480 
    87475  87476 
    87044  87044 
    26662  26662 
    21870  21870 
    21870  21870 

因为我知道这是一个主要的性能缺陷。所有这些SQL语句都是存储过程或使用绑定变量。我还重用了C#中调用存储过程的命令对象。

如何减少此解析呼叫的数量?

此外,有一些方法可以区分硬解析和软解析吗?

编辑

正如@DCookie提到我跑了数据库以下查询。

SELECT s2.name, SUM(s1.value) 
FROM v$sesstat s1 join v$statname s2 on s1.statistic# = s2.statistic# 
WHERE s2.name LIKE '%parse count%' 
GROUP BY s2.name 
ORDER BY 1,2; 

结果如下

"NAME"       "SUM(S1.VALUE)" 
"parse count (describe)"    0 
"parse count (failures)"    29 
"parse count (hard)"     258 
"parse count (total)"    11471 

所以似乎很难解析的数量相比,解析的数量是非常低的。感谢大家对他们的回答:)

最后更新:

用于解析的主要问题是因为我们有连接池的连接字符串中关闭。打开连接池后,我能够完全解决分析问题。

+0

我假设,存储过程被编译并且不运行'EXECUTE IMMEDIATE'语句? – 2011-06-01 11:44:47

+0

是的。一切都编译完成。没有'EXECUTE IMMEDIATE'语句。 – 2011-06-01 11:48:04

+1

这很可能与共享池设置有关,但我不记得如何检查。我相信这将很快回答 – 2011-06-01 11:50:32

回答

2

开始与此:

SELECT name, SUM(value) 
    FROM v$sesstat s1 join v$statname s2 on s1.statistic# = s2.statistic# 
WHERE s1.name LIKE '%parse count%' 
GROUP BY name 
ORDER BY 1,2; 

这会给你硬解析和总解析的数量。您的查询中的parse_calls值是全部解析,非常硬和软。

你的SQL做什么?没有太多的游标处理,大多是单个语句?你得到的执行与解析的比率几乎是1-1,如果它们是软解析,则意味着你没有做太多的游标处理。

编辑:

除非你能修改代码以打开,并挂在每一个SQL语句的光标,并在会话中尽可能多地重用他们,我不认为你能避免解析。

+1

在我的Oracle版本(10.2)中,那些统计值#值不匹配任何内容。将谓词改为'WHERE name LIKE'parse count%''也许会更好。 – 2011-06-01 14:18:44

+0

@Dave,好点。编辑答案。 – DCookie 2011-06-01 14:36:36

+0

@Dave,我是在一个11g数据库上,就像OP一样,它很可能会工作。一般来说,你的观点仍然有效。 – DCookie 2011-06-01 14:48:41

1

即使语句位于库缓存中,每次创建新的游标时都必须发生解析调用。它是检查库缓存的解析调用。如果语句在库缓存中找到,则它是一个软解析。

@DCookie回答了您关于检查硬对比软解析计数的问题。我希望你会发现大多数解析调用都是软解析。请注意,您不应期望从v$sysstat返回的计数与从v$sql开始的总解析调用非常接近,因为前者是实例启动后的计数,后者仅显示当前位于库缓存中的语句。

完全避免解析调用的唯一方法是保留现有游标的句柄,并在需要时执行它,在适当时绑定新值。这有时会通过缓存游标发生 - 它超出了您的显式控制范围,尽管我相信您可以更改参数来影响它。在PL/SQL代码中,您可以显式地保存使用DBMS_SQL包创建和管理的游标。我希望C#具有相应的功能。

无论如何,你在看什么可能不是问题。仅仅因为计数似乎很高,绝不意味着解析是系统的瓶颈。

首先,您应该检查具有这些高分析计数的SQL语句是否在您的控制之下。当我做您的查询的修改版本,在我的系统之一:

select parse_calls, executions, parsing_schema_name,sql_text 
FROM v$sql 
ORDER BY parse_calls DESC; 

我发现与解析调用次数最多的声明是由SYS解析的递归SQL。根据您的使用情况,这可能不是您的情况,但需要检查。

+0

所有具有高分析计数的SQL语句都在我的控制之下。我从查询中删除了'sql_text'部分,并且在发布问题时有目的的结果:) – 2011-06-01 16:40:27