Oracle - 参数化查询有 EXECUTIONS = PARSE_CALLS
我们有一个与 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
解析查询的次数完全取决于调用应用程序。每次应用程序要求数据库解析查询时,都会解析一次查询。
服务器端,有 不同类型的解析:
在您的情况下,您很可能在每个会话中创建一次语句,然后将其丢弃,因此 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:
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.
可能是因为 .NET 程序员选择在伪代码中编写这样的例程:
他们应该这样编码:
或者甚至更好:使用单个查询来检索所有 someId/anotherId 的所有
数据
抢。
Likely because the .NET programmers have chosen to code a routine like this in pseudocode:
where they should have coded it like this:
Or even better: use a single query to retrieve for all data for all someId's/anotherId's
Regards,
Rob.