很多时候,我只想N从查询中检索第一行,但我事先不知道N会是什么。例如:
try(var stream = sql.selectFrom(JOB)
.where(JOB.EXECUTE_AFTER.le(clock.instant()))
.orderBy(JOB.PRIORITY.asc())
.forUpdate()
.skipLocked()
.fetchSize(100)
.fetchLazy()) {
// Now run as many jobs as we can in 10s
...
}
Run Code Online (Sandbox Code Playgroud)
现在,在不添加任意 LIMIT 子句的情况下,PG 查询规划器有时会决定对此类查询进行极其缓慢的顺序表扫描,据我所知,因为它认为我将获取结果集中的每一行。任意 LIMIT 类型适用于像这样的简单情况,但我根本不喜欢它,因为:
N行。N足够大的查询而不破坏您的代码可能会很困难。您不想成为下一个必须理解该代码的人。那么,我如何告诉查询规划器我只会获取几行,并且快速获取第一行是这里的优先事项?这可以使用 JDBC API/驱动程序来实现吗?
(注意:我不是在寻找间接影响查询规划器的服务器配置调整,例如修改随机页面成本,也不能接受类似的解决方法set seq_scan=off)
(注2:为了清楚起见,我在示例代码中使用了 jOOQ,但在幕后这只是另一个PreparedStatement使用ResultSet.TYPE_FORWARD_ONLYand ResultSet.CONCUR_READ_ONLY,所以据我所知,我们可以排除错误的语句模式)
(注3:我没有处于自动提交模式)