3

我的 JDeveloper ADF Web 应用程序中运行的查询存在一个奇怪的问题。它是一个向 Oracle 10g 数据库发出选择语句的简单搜索表单。提交搜索时,ADF 框架(首先)运行查询,(第二)运行包装在“ select count(1) from (...query...)”中的相同查询——这里的目标是获取总行数,并显示“接下来的 10 个结果”导航控件。

到目前为止,一切都很好。麻烦来自我从第二个查询(其中带有“ count(1)”的查询)中获得的令人发指的性能。为了调查这个问题,我在 SQL Developer 中复制/粘贴/运行了查询,并惊讶地看到更好的响应。

在比较 ADF 和 SQL Developer 中的查询执行时,我采取了所有措施来确保两种执行的代表性环境: - 新重新启动的数据库 - 对于 OC4J 相同这样我可以确定差异与缓存和/或缓冲无关,在这两种情况下,数据库和应用程序服务器都是新(重新)启动的。

我为这两个会话所做的跟踪说明了这种情况:

查询在 ADF 中运行:

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          0          0          0           0
Execute      1      0.97       0.97          0          0          0           0
Fetch        1     59.42     152.80      35129    1404149          0           1
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        3     60.39     153.77      35129    1404149          0           1

SQL Developer 中的相同查询:

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          0          0          0           0
Execute      1      1.02       1.16          0          0          0           0
Fetch        1      1.04       3.28       4638       4567          0           1
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        3      2.07       4.45       4638       4567          0           1

提前感谢您的任何意见或建议!

4

4 回答 4

3

好的,我终于找到了这种可怕行为的解释。长话短说,答案在 JDeveloper 中我的 ViewObject 的定义(调整参数)中。我缺少的是这两个重要参数:

  • FetchMode="FETCH_AS_NEEDED"
  • FetchSize="10"

没有它们,会发生以下情况 - ADF 运行主查询、绑定变量并获取结果。然后,为了估计行数,它启动包含在“ select count(1) from (my_query)”中的相同查询,但是......(鼓声)......没有绑定变量!!!在不考虑绑定变量的实际值的情况下估计行数有什么用,这真的让我大吃一惊!

无论如何,这一切都在 ViewObject 的定义中:需要设置以下设置,以获得预期的行为:

  • 批次中的所有行:10
  • (选中)根据需要
  • (未选中)通过行集分页时填充行的最后一页

执行计划对我没有帮助(ADF 和 SQL Developer 都是相同的),差异仅在使用绑定获取的跟踪文件中可见。

所以,现在我的问题已经解决了——感谢所有最终导致我解决问题的提示!

于 2010-09-01T06:39:05.940 回答
1

使用 count 的查询速度较慢,因为它必须读取所有数据(对其进行计数)。

当您运行另一个查询时,您只获取第一页数据,因此在您获得前十个结果后,执行(从游标读取)可以停止。

尝试使用您的第一个查询加载到第 100 页,它可能会比第一页慢得多。

如果在线选择一个计数太昂贵,一个常见的技巧是选择一个比您需要的多的项目(在您的情况下为 11 个)以确定是否有更多数据。您不能显示页数,但至少显示“下一页”按钮。

更新:您是说计数查询仅在通过 ADF 运行时很慢,但通过 SQL Developer 运行时很快?

于 2010-08-31T09:51:29.163 回答
1

如果是同一个查询,我可以想到:

  • ADF 与 SQL Developer 中的不同设置(您是否尝试过使用 SQL*Plus?)
  • 在慢速情况下绑定类型不正确的变量

但是没有执行计划或 SQL,很难说

于 2010-08-31T11:14:27.433 回答
1

多年来,我发现“SELECT COUNT...”通常会导致意外减速。

如果我理解上面发布的结果,从 JDeveloper 查询需要 153 秒,但从 SQL Developer 只需要大约 4.5 秒,您将使用此查询来确定是否应显示“下一个 10 个结果”控件。

我不知道运行时间是 4.5 秒还是 153 秒是否重要——即使是最好的情况,初始化页面似乎也相当慢。假设您可以在从页面提交时让查询在 4.5 秒内响应 - 这仍然是让用户坐下来等待的时间很长,因为他们只需单击鼠标就可以开始做其他事情. 在同样的 4.5 秒内,应用程序可能能够获取足够的数据来多次加载页面。

我认为@Thilo 的想法是获取比填充页面所需的多一条记录以确定是否有更多可用数据。也许这可以适应你的情况?

分享和享受。

于 2010-08-31T11:24:30.190 回答