减少Oracle中的Parse调用

时间:2011-06-01 11:39:35

标签: c# sql performance oracle oracle11g

我注意到parse_calls等于Oracle 11g数据库中的执行次数。

 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

因此,与解析数量相比,硬解析的数量似乎非常低。感谢大家的回复:)

最终更新:

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

2 个答案:

答案 0 :(得分: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 :(得分: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。根据您的使用情况,这可能不是您的情况,但需要检查。