PageHelper 分页原理及大数据量查询性能问题的解决办法

   日期:2024-11-07    作者:caijiyuan 移动:http://g8akg8.riyuangf.com/mobile/quote/2099.html

PageHelper.startPage(1,3)

 

开始执行真正的select语句

PageHelper 分页原理及大数据量查询性能问题的解决办法

public Page doSelectPage(ISelect select) { select.doSelect(); return this; }

进入MapperProxy类执行invoke方法获取到方法名称及参数值

 

接着是MapperMethod方法执行execute语句,判断是增、删、改、查。判断返回值是多个,进入executeForMany方法

 

这个方法开始调用SqlSessionTemplate、DefaultSqlSession等类获取到Mapper.xml文件的SQL语句

 

开始进入PageHelper的真正实现,Plugin通过实现InvocationHandler进行动态代理获取到相关信息

 

PageInterceptor 实现Mybatis的Interceptor 接口,进行拦截

 

转到ExecutorUtil抽象类的pageQuery方法

 

在抽象类AbstractHelperDialect的getPageSql获取到对应的Page对象

 

进入到MySqlDialect类的getPageSql方法进行SQL封装,根据page对象信息增加Limit。分页的信息就是这么拼装起来的

 

将最后拼装好的SQL返回给DefaultSqlSession执行查询并返回

 

PageHelper的分页功能是通过Limit拼接SQL实现的。

问题来了 分析SQL语句,limit在数据量少或者页数比较靠前的时候查询效率是比较高的。(单表数据量百万进行测试)

select * from user where age = 10 limit 1,10;结果显示0.43s

当where条件后的结果集较大并且页数达到一个量级整个SQL的查询效率就十分低下(哪怕where的条件加上了索引也不行)。

select * from user where age = 10 limit 100000,10;结果显示4.73s

那有什么解决方案呢

分页的方案 原来的分页SQL

select * from 表名 limilt 155555,20 1 优化后的sql语句

select * FROM 表名 WHERe ‘id’ in (select id from 表名 LIMIT 155555,20)

首先开启 PageHelper.startPage(pageParam.getPageNum(), pageParam.getPageSize()); 必然会在sql的后面追加 155555,20 而我们的优化后的SQL的limit是一个子查询语句如何解决?,此时仍然按照以前的做法会得到

SELECt * FROM 表名 WHERe ‘id’ in (select id from 表名 ) LIMIT 155555,20

 

Mapper文件


特别提示:本信息由相关用户自行提供,真实性未证实,仅供参考。请谨慎采用,风险自负。


举报收藏 0评论 0
0相关评论
相关最新动态
推荐最新动态
点击排行
{
网站首页  |  关于我们  |  联系方式  |  使用协议  |  隐私政策  |  版权隐私  |  网站地图  |  排名推广  |  广告服务  |  积分换礼  |  网站留言  |  RSS订阅  |  违规举报  |  鄂ICP备2020018471号