为啥分页查询比使用 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 Boot中使用Spring-data-jpa实现分页查询(转)
spring data jpa Specification 复杂查询+分页查询
当列表分页的大小输入设置为大于 15 时,Spring Data PagedListHolder 没有返回正确的 PageSize,为啥?