gpt4 book ai didi

java - 只有当查询包含 FIRST_ROWS 或 ROWNUM 限制时,ResultSet.next 才会非常慢

转载 作者:搜寻专家 更新时间:2023-11-01 02:52:24 25 4
gpt4 key购买 nike

我使用

执行 native 查询
entityManager.createNativeQuery(sqlQuery);
query.setMaxResults(maxResults);

List<Object[]> resultList = query.getResultList();

为了加快查询速度,我想包含 FIRST_ROWS(n) 提示或使用 WHERE ROWNUM > n 进行限制。

使用检测,我发现 OraclePreparedStatement.executeQuery 确实更快,但是在 EJBQueryImpl.getResultList 上花费了更多时间,导致整体性能非常差。更详细地观察,我发现每 10 次调用 ResultSet.next() 所花费的时间与 executeQuery 本身 () 一样长。当我省略查询提示或 ROWNUM 条件时,这种奇怪的行为就会停止,然后每 10 次调用 resultset.next 会比其他调用低一些,但只有 2 毫秒而不是 3 秒。

最佳答案

当你包含提示时,你会得到不同的查询计划吗?我的假设是您根据您对问题的描述来做。

当您在 Oracle 中执行查询时,数据库通常不会在任何时间点具体化整个结果集(显然,如果您指定需要所有的 ORDER BY 子句,则可能必须这样做在排序发生之前要具体化的数据)。直到客户端开始获取数据,Oracle 才真正开始具体化数据。它运行足够的查询以生成客户端要求获取的行数(在您的情况下听起来像是 10 行),将这些结果返回给客户端,并等待客户端请求更多数据,然后再继续处理查询。

这听起来像是在包含 FIRST_ROWS 提示时,查询计划正在以某种方式发生变化,使其执行起来更加昂贵。显然,这不是 FIRST_ROWS 提示的目标。目标是告诉优化器生成一个计划,使获取前 N 行的效率更高,即使它使从查询中获取所有行的效率降低。这往往会导致优化器更喜欢索引扫描而不是表扫描,其中表扫描总体上可能更有效。然而,在您的情况下,这听起来像是优化器的估计不正确,它最终选择了一个通常效率较低的计划。这通常意味着您的查询所引用的某些对象的某些统计信息不完整或不正确。

关于java - 只有当查询包含 FIRST_ROWS 或 ROWNUM 限制时,ResultSet.next 才会非常慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8861332/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com