Oracle - 参数化查询有 EXECUTIONS = PARSE_CALLS

发布于 2024-09-01 07:13:45 字数 467 浏览 3 评论 0原文

我们有一个与 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?

We have a .NET application talking to Oracle 10g. Our DBA recently pulled a list of queries where executions is equal to parse_calls. We assumed that this would help us find all of the unparameterized queries in our code.

Unexpectedly, the following query showed up near the top of this list, with 1,436,169 executions and 1,436,151 parses:

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))

Why is executions equal to parse_calls for this query?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

挽梦忆笙歌 2024-09-08 07:13:45

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

服务器端,有 不同类型的解析

  • 硬解析——查询从未
    以前见过,不在共享中
    水池。我们必须解析它,散列它,
    在共享池中查找,不要
    找到它,安全检查它,优化
    它等等(大量的工作)。

  • 软解析——查询已被
    之前看到的,是在共享池中。我们
    必须解析它,散列它,查看
    共享池并找到它
    (比硬解析工作少,但工作
    尽管如此)

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

尽管如此,您仍然可以在应用程序中缓存该语句并重用它,以便每个会话仅(软)解析一次。

the number of times a query is parsed is entirely dependent upon the calling application. A query will be parsed once each time the application asks the database to parse it.

Server side, there are different kinds of parse:

  • HARD parse -- the query has never
    been seen before, isn't in the shared
    pool. We must parse it, hash it,
    look in the shared pool for it, don't
    find it, security check it, optimize
    it, etc (lots of work).

  • SOFT parse -- the query has been
    seen before, is in the shared pool. We
    have to parse it, hash it, look in
    the shared pool for it and find it
    (less work then a hard parse but work
    none the less)

Most likely in your case you are creating the statement once per session and then discard it so Oracle has to parse it each time. However, thanks to parameterizing, this parse is a soft one and Oracle only gets to the expensive step of optimizing it once.

Still, you can probably cache the statement in your application and reuse it, so as to (soft) parse it only once per session.

一曲琵琶半遮面シ 2024-09-08 07:13:45

可能是因为 .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 的所有

数据
抢。

Likely because the .NET programmers have chosen to code a routine like this in pseudocode:

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;

where they should have coded it like this:

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);

Or even better: use a single query to retrieve for all data for all someId's/anotherId's

Regards,
Rob.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文