为啥分页查询比使用 Spring Data 的普通查询慢?

Posted

技术标签:

【中文标题】为啥分页查询比使用 Spring Data 的普通查询慢?【英文标题】:Why is a paginated query slower than a plain one with Spring Data?为什么分页查询比使用 Spring Data 的普通查询慢? 【发布时间】:2017-10-16 17:28:19 【问题描述】:

鉴于我有一个简单的查询:

List<Customer> findByEntity(String entity);

此查询在 700 毫秒内返回 7k 条记录。

Page<Customer> findByEntity(String entity, Pageable pageable);

此查询在 1080 毫秒内返回 10 条记录。我知道分页的额外计数查询,但似乎仍有一些问题。我还注意到一件奇怪的事情是,如果我将页面大小从 10 增加到 1900,响应时间在 1080 毫秒左右完全相同。

有什么建议吗?

【问题讨论】:

【参考方案1】:

分页方法运行两个查询:

1) select count(e.id) from Entity e //to get number of total records
2) select e from Entity e limit 10 [offset 10] //'offset 10' is used for next pages

第一个查询在 7k 条记录上运行缓慢,恕我直言。

Spring Data 即将发布的 Ingalis 将使用改进的分页查询算法 (more info)。

有什么建议吗?

我认为使用包含 7k 条记录的分页查询是没有用的。你应该限制它。

【讨论】:

【参考方案2】:

这可能确实是计数查询在这里很昂贵。如果您坚持要知道集合中匹配的元素总数,那么不幸的是无法绕过该附加查询。但是,如果您能够牺牲返回的信息,则有两种可能性可以避免更多的开销:

    使用Slice 作为返回类型Slice 没有公开查找元素总数的方法,但它允许您查找下一个切片是否可用。我们通过读取比请求的多一个元素并使用其(不)存在作为下一个切片可用性的指标来避免此处的计数查询。 使用List 作为返回类型——这将简单地将分页参数应用于查询并返回所选元素的窗口。但是,它不会让您知道后续数据是否可用。

【讨论】:

以上是关于为啥分页查询比使用 Spring Data 的普通查询慢?的主要内容,如果未能解决你的问题,请参考以下文章

Spring Data Jpa 使用@Query标注自定义查询语句

Mongodb系列- 使用spring-data-mongodb实现分页查询

spring data mongodb Query 及分页

在Spring Boot中使用Spring-data-jpa实现分页查询(转)

spring data jpa Specification 复杂查询+分页查询

当列表分页的大小输入设置为大于 15 时,Spring Data PagedListHolder 没有返回正确的 PageSize,为啥?