我们可以在 JPA 查询中一起使用 HINT_FETCH_SIZE 和 Pageable 吗

Can we use HINT_FETCH_SIZE and Pageable together in JPA query

我的 JpaRepository 中有如下查询。 我的 Pageable 大小为 1000 条记录,但 HINT_FETCH_SIZE 为 50。 这是否意味着要填充 1000 条记录的 Page,此查询被调用 20 次(20 x 提取大小 50)? 我的理解正确吗? 如果我们需要 Pageable 的 1000 条记录,理想的 HINT_FETCH_SIZE 是多少?

@QueryHints(value = @QueryHint(name = HINT_FETCH_SIZE, value = "50"))
@Query("SELECT m FROM sales m " +
        "WHERE m.settlementDate >= :start " +
        "AND m.settlementDate < :end " +
        "ORDER BY m.salesId")
Page<Sales> findBySettlementDatePage(
        @Param("start") LocalDate start,
        @Param("end") LocalDate end,
        Pageable pageable);

Does this mean to fill the Page of 1000 records, this query is called 20 times (20 x fetch size 50)?

没有。 该查询每页只会执行一次。 提取大小决定了数据库在等待客户端发出信号表明它已经处理了到目前为止发送的所有行之前应该一次发送多少行,这是通过访问 ResultSet 中的所有行自动发生的,这又发生在结果由 JPA 实现转换为 List 或类似的。

当并非所有行都适合内存时,这尤其有用。 所以这个论点没有那么重要。

您的数据库可能做的另一件事是针对指定的提取大小优化查询计划。 这意味着它会尝试尽快将前 n 行带给您,即使这可能会花费更长的时间来获取所有行。

由于您必须先填充一个 Page 对象才能继续您的程序,因此您希望您的提取大小如此之大,以便一次性提取单个页面的所有数据。 对于一个简单的实体,这可能恰好是 Page 中的行数。 但是,如果实体具有急切获取的一对多关系,它实际上可能会执行连接并获取超过 1000 行的方式。

到目前为止的理论。 实际上,您不应该指定提取大小,而只需将其留给数据库驱动程序即可。 并且只有当您发现问题(或有充分理由期待出现问题)时,您才应该实际尝试不同的提取大小,以了解您的场景的最佳价值在哪里。