我使用执行本机查询
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 行的效率更高,即使它会使从查询中获取所有行的效率降低。这往往会导致优化器更喜欢索引扫描而不是表扫描,其中表扫描总体上可能更有效。然而,在您的情况下,优化器的估计是不正确的,它最终会选择一个通常效率较低的计划。这通常意味着您的查询引用的某些对象的某些统计信息不完整或不正确。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)