我很想知道在使用OFFSET和LIMIT
我们尝试使用 JOOQs 合成 SEEK 子句,但是因为我们的 ID 是无序的 UUID,所以它不起作用。
我们当前的实现是执行查询两次,第一次是在我们设置偏移量和限制以获取结果/行数之前。
然后我们在第二个查询中得到结果。
SelectQuery<Record> select = context.selectQuery();
select.addSelect(FOO_TABLE.fields());
select.addFrom(FOO_TABLE);
int totalElements = select.fetch().size();
select.addOffset(20);
select.addLimit(50));
List<Foo> paginatedFoo = select.fetchInto(Foo.class);
Run Code Online (Sandbox Code Playgroud)
这只是这个实现/设计必须接受的东西,还是有任何 JDBC 驱动程序魔术可以消除在数据库上执行两个查询的需要?
欢迎任何意见或建议!
我们尝试使用 JOOQs 合成 SEEK 子句,但是因为我们的 ID 是无序的 UUID,所以它不起作用。
分页时,您按对用户有意义的内容排序。因此,您可能需要先对其他一些列进行排序/查找(例如某DATE列),然后使用UUIDonly 来获得明确、稳定的结果。我不明白为什么SEEK不适合你。
如果使用SEEK(keyset pagination)对您的应用程序有意义,从逻辑上讲,出于性能原因,它是更可取的:
这只是这个实现/设计必须接受的东西,还是有任何 JDBC 驱动程序魔术可以消除在数据库上执行两个查询的需要?
数据库需要做很多额外的工作。特别是如果你这样做:
// Don't do this!
int totalElements = select.fetch().size();
Run Code Online (Sandbox Code Playgroud)
您现在正在传输整个数据集!如果您必须计算单独查询中的行数,请至少在数据库中完全运行该查询:
// Do this instead (prior to adding the limit):
context.fetchCount(select);
Run Code Online (Sandbox Code Playgroud)
但是为什么不直接使用窗口函数呢?添加DSL.count().over()到您的查询以计算如果您没有分页,您的查询将产生的总行数,并且您已经全部设置好了。
为什么你可以使用窗口功能,这样做的原因是因为他们所有的其它操作(后方便计算WHERE,GROUP BY,HAVING,等),但前分页(OFFSET,LIMIT)。请参阅有关操作的逻辑顺序的这篇文章。
| 归档时间: |
|
| 查看次数: |
350 次 |
| 最近记录: |