大部分时间开发的分页代码都是使用pagehelper.PageInfo分页插件来实现,简单方便 PageHelper.startPage(1, 10)
遇到百万数据量SQL,在进行分页查询时会出现性能问题,分页越深越慢
我们要知道PageHelper的分页原理是什么
- pageHelper 在执行时,会先计算count 数量,在通过sql拼接limit 实现分页功能,所以每次点下一页时,都会重新执行两遍SQL语句,是相当的慢。
- 当where条件后的结果集较大并且页数达到一个量级整个SQL的查询效率就十分低下(哪怕where的条件加上了索引也不行)
解法:
- 如果是管理后台的分页,提供两个接口,count计算总数的合并接口,合并接口并做缓存处理。
前端设置请求唯一uuid,并与合计请求接口关联,这样实现的效果就是每次点击下一页时,合并接口可以快速返回缓存数据
当下次请求发生变动时,uuid发送变化又是新的一条数据。
当然前端也要做好接口异步加载的逻辑,分页接口返回快,优先展示分页数据,再渲染合并接口数据
这里用到的优化思想就是用缓存来空间换时间,接口并行分而治之
- 去掉pageHelper,自定义分页,分开定义count 和page sql语句
count sql语句,做法是返回当前搜索条件的下的count(*) , MAX(pk_id) 总数和最大的主键id
select count(*) count, MAX(pk_id) maxId
from xx_record
page sql语句,使用join或者子查询去优化
select
t2.*
from xx_record t2 inner join (
select pk_id from xx_record t1
WHERE pk_id <= #{maxId}
limit #{pageNumber},#{pageSize}
) a on a.pk_id = t2.pk_id
ORDER BY t2.pk_id