我有一个大型数据库(30百万行)。
现在发现用PagingAndSortingRepository
和Pageable
来限制查询有很差的性能,但是为什么呢?
interface MyRepo extends PagingAndSortingRepository<MyEntity, Long> {
@Query(value = "SELECT * FROM mytable ORDER BY id limit 10",
nativeQuery = true)
List<Object> findAllLimited();
@Query(value = "SELECT * FROM mytable",
countQuery = "SELECT count(*) FROM mytable ORDER BY id",
nativeQuery = true)
Page<Object> findAllPageable(Pageable pageable);
}
用法:
dao.findAllLimited(); //10ms
dao.findAllPageable(PageRequest.of(0, 10)); //20000ms
为什么通过PagingAndSortingRepository
的Page
请求会这么慢?这里使用原生查询还是普通查询都没有关系。只要我尝试通过Pageable
应用分页/限制,性能就会崩溃。
知道为什么会出现这种情况吗?原生LIMIT 10
方法证明了DB通常能够及时地提供结果。
该表的定义如下:
CREATE TABLE mytable (
id bigint NOT NULL AUTO_INCREMENT,
...
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1条答案
按热度按时间ffscu2ro1#
Slice<Object> findBy(Pageable pageable)
解决了这个问题!所以上面的评论是正确的:瓶颈是Spring为每个页面额外执行的count
查询。如果有人对此有一个解决方案,可以保留
Page
及其总元素计数,但不必对每个页面请求执行计数,请发表评论。除此之外,切片解决方案是有效的,只是人们不知道还有多少页要写。