我的JDeveloper ADF Web应用程序中运行的查询存在一个奇怪的问题。它是一个向Oracle 10g数据库发出select语句的简单搜索表单。提交搜索时,ADF框架(首先)运行查询,(第二)运行包含在“select count(1) from (...query...)
”内的相同查询 - 这里的目标是获取总行数,并显示“接下来的10个结果”导航控件。
到目前为止,这么好。麻烦来自于我从第二个查询(其中包含“count(1)
”的查询)获得的令人发指的表现。为了研究这个问题,我在SQL Developer中复制/粘贴/运行了查询,并且惊讶地看到了更好的响应。
在比较ADF和SQL Developer中的查询执行时,我采取了所有措施来确保两个执行的代表性环境: - 刚重新启动的数据库 - 同样适用于OC4J 通过这种方式,我可以确定差异与缓存和/或缓冲无关,在这两种情况下,db和应用程序服务器都是刚刚(重新)启动的。
我为两个会议所采取的痕迹说明了这种情况:
在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
提前感谢您的任何意见或建议!
答案 0 :(得分:3)
好的,我终于找到了这种可怕行为的解释。总而言之,答案在于JDeveloper中我的ViewObject的定义(调整参数)。我缺少的是这两个重要参数:
没有它们,会发生以下情况 - ADF运行主查询,绑定变量并获取结果。然后,为了估计行数,它会启动包含在“select count(1) from (my_query)
”中的相同查询,但是......(鼓滚)...没有绑定变量!!!在没有考虑绑定变量的实际值的情况下,估计行数的用途真的很好!
无论如何,它都在ViewObject的定义中:需要设置以下设置,以获得预期的行为:
执行计划无法帮助我(对于ADF和SQL Developer来说都是一样的),差异仅在使用绑定的跟踪文件中可见。
所以,现在我的问题已经解决了 - 感谢所有提示最终促使我解决的问题!
答案 1 :(得分:1)
带有计数的查询较慢,因为它必须读取所有数据(计算它)。
当您运行另一个查询时,您只获取第一页数据,因此在获得前十个结果后,执行(从光标读取)可能会停止。
尝试使用第一个查询加载到第100页,它可能比第一页慢得多。
如果选择在线计数过于昂贵,常见的诀窍是选择一个项目超过您需要的项目(在您的情况下为11)以确定是否有更多数据。您无法显示页数,但至少显示“下一页”按钮。
更新:您是说在通过ADF运行时计数查询速度很慢,但是快速通过SQL Developer?
答案 2 :(得分:1)
如果是同一个查询,我可以想到:
但是没有执行计划或SQL,很难说
答案 3 :(得分:1)
多年来我发现“SELECT COUNT ...”通常是意外减速的原因。
如果我理解上面发布的结果,那么JDeveloper的查询需要153秒,但SQL Developer只需要4.5秒,您将使用此查询来确定是否应显示“Next 10 Results”控件
我不知道如果运行时间是4.5秒或153秒也很重要 - 即使最好的情况似乎也很慢,初始化页面。暂时假设您可以在从页面提交的4.5秒内让查询响应 - 这仍然需要很长时间才能让用户坐下来等待他们只需点击鼠标即可离开去做其他事情。在同样的4.5秒内,应用程序可能能够获取足够的数据来加载页面几次。
我认为@ Thilo想要获取一条记录,而不是填充页面以确定是否有更多可用数据是一个好的记录。也许这可以适应你的情况?
分享并享受。