首页 > 解决方案 > 我们可以在 JPA 查询中同时使用 HINT_FETCH_SIZE 和 Pageable

问题描述

我的JpaRepository. 我的Pageable大小为 1000 条记录,但HINT_FETCH_SIZE为 50。这是否意味着填充Page1000 条记录,此查询被称为 20 次(20 x fetch size 50)?我的理解正确吗?HINT_FETCH_SIZE如果我们需要Pageable1000 条记录,理想的情况是什么?

@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);

标签: spring-data-jpafetchpageable

解决方案


这是否意味着要填充 1000 条记录的页面,这个查询被调用 20 次(20 x fetch size 50)?

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

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

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

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

理论到此为止。在实践中,您不应该指定获取大小而将其留给数据库驱动程序。只有当您看到问题(或有充分的理由期待一些问题)时,您才应该实际尝试不同的提取大小,以查看您的方案的最佳价值在哪里。


推荐阅读