参考资料:Mysql分页以及优化的几种方式。_技术砖家--Felix的博客-CSDN博客_mysql 分页优化
(本文采用的是参考文章中分页优化的第三种,子查询方式,第四种试了一下,十多秒页面才出数据)
准备两个表(存数据的表 和 存对应的表的总数)
测试表(存放数据):
总数表(存放count数据 。当然,对应的表每做一次添加删除也需要修改这个表的数据。如果数据在一百万以内不需要使用,性能还是可以的):
mybatis实现:
mapper接口:
/**
* 分页
* @param currentPage 当前页
* @param pageSize 分页大小
* @return 结果集
*/
List<EmployeeExporter> getAll(@Param("currentPage") Integer currentPage,
@Param("pageSize") Integer pageSize);
xml:
<select id="getAll" resultType="EmployeeExporter">
SELECT id, user_name, gender, age, birthday, national_area, city
FROM `employee`
WHERE id >=
(SELECT id FROM `employee` where deleted = 0 ORDER BY id
LIMIT #{currentPage}
, 1)
and deleted = 0
LIMIT #{pageSize}
</select>
controller(测试代码直接省略service):
@GetMapping("all")
@ApiOperation("查找")
public ResultVo<Object> findAll(Integer currentPage, Integer pageSize) {
// 重新计算当前页规则
currentPage =((currentPage -1) * pageSize);
//这里就是调用接口 拿到当前页的结果集
List<EmployeeExporter> records = mapper.getAll(currentPage, pageSize);
//这里是把总数放在一个计数表,毕竟数据量大了的话 select count(*) 执行很慢。所以就是直接返回结果
LambdaQueryWrapper<CountPojo> wrapper = Wrappers.lambdaQuery(CountPojo.class)
.eq(CountPojo::getName, "employee");
//自定义一个count对象。用来存储对应的表的count总数据数
CountPojo count = countMapper.selectOne(wrapper);
//Integer total = mapper.getIdCount();
log.info("records : {}", records);
//以下是将结果集存放到map中。然后丢到result对象返回给前端
HashMap<String, Object> map = getMap(2);
map.put("data", records);
map.put("total", count.getCount());
return ResultVo.success(map);
}
mybatis-plus实现:
@GetMapping("all")
@ApiOperation("查找")
public ResultVo<Object> findAll(Integer currentPage, Integer pageSize) {
// 注:last条件中limit后面需要加空格(limit0,1)和 (limit 0,1)看懂了吗
currentPage =((currentPage -1) * pageSize);
//子查询条件
LambdaQueryWrapper<EmployeeExporter> sonSelect = Wrappers.lambdaQuery(EmployeeExporter.class).select(EmployeeExporter::getId)
.orderByAsc(EmployeeExporter::getId).last("limit " + currentPage + ",1");
//拿到子查询对象的id
EmployeeExporter one = excelService.getOne(sonSelect);
LambdaQueryWrapper<EmployeeExporter> select = Wrappers.lambdaQuery(EmployeeExporter.class)
.ge(EmployeeExporter::getId, one.getId())
.last("limit " + pageSize);
//结果集
List<EmployeeExporter> records = excelService.list(select);
LambdaQueryWrapper<CountPojo> count = Wrappers.lambdaQuery(CountPojo.class)
.eq(CountPojo::getName, "employee");
CountPojo total = countMapper.selectOne(count);
HashMap<String, Object> map = getMap(2);
map.put("data", records);
map.put("total", total.getCount());
return ResultVo.success(map);
return plusResultPlus(currentPage, pageSize);
}
测试:
element ui + springboot
第一页:
随机一页:
最后一页:
可以看到执行时间还是挺理想的。最后一页三百万也就一秒左右,也不知道属不属于慢sql了。
当然,可能有很多细节没考虑到,但总之还是实践了一下。