Oracle - 参数化查询具有EXECUTIONS = PARSE_CALLS

时间:2010-05-11 13:42:52

标签: .net sql oracle oracle10g

我们有一个与Oracle 10g交谈的.NET应用程序。我们的DBA最近提取了一个查询列表,其中执行等于parse_calls。我们假设这有助于我们在代码中找到所有未参数化的查询。

出乎意料的是,以下查询显示在此列表的顶部附近,有1,436,169次执行和1,436,151次解析:

SELECT bar.foocolumn
  FROM bartable bar,
       baztable baz
 WHERE bar.some_id = :someId
   AND baz.another_id = :anotherId
   AND baz.some_date BETWEEN bar.start_date AND (nvl(bar.end_date, baz.some_date + (1/84600)) - (1/84600))

为什么执行等于此查询的parse_calls?

2 个答案:

答案 0 :(得分:3)

可能是因为.NET程序员选择在伪代码中编写这样的例程:

Loop over someId's and anotherId's
  parse(your_query);
  bind someId and anotherId to your_query;
  execute(your_query);
  close(your_query);
end loop;

他们应该像这样编码:

parse(your_query);
Loop over someId's and anotherId's
  bind someId and anotherId to your_query;
  execute(your_query);
end loop;
close(your_query);

甚至更好:使用单个查询来检索所有someId / anotherId的所有数据

此致 罗布。

答案 1 :(得分:3)

解析查询的次数完全取决于调用应用程序。每次应用程序要求数据库解析时,都会解析一次查询。

服务器端,有different kinds of parse

  
      
  • HARD解析 - 查询永远不会   以前见过,不是在分享   池。我们必须解析它,哈希它,   查看共享池,不要   找到它,安全检查,优化   它等等(很多工作)。

  •   
  • SOFT解析 - 查询已经完成   之前看到的是在共享池中。我们   必须解析它,哈希它,看看   它的共享池并找到它   (较少的工作然后是硬解析但工作   (尽管如此)

  •   

在您的情况下,您最有可能每个会话创建一次语句,然后将其丢弃,以便Oracle每次都必须解析它。但是,由于参数化,这个解析是一个软解析,而Oracle只需要进行一次优化的昂贵步骤。

但是,你可以在你的应用程序中缓存该语句并重用它,以便(软)每次会话只解析一次。