关于mysql大数据量分页方法
关于mysql大数据量分页方法
一个mysql大数据分页方法,权当笔记,方便以后随时捡起。
刚来公司时,看到一个同事提到一种mysql大数据量分页方式,当时没感觉到价值所在,直到我也遇到同样的问题
mysql中 平时我们分页都是用limit num1,num2 ,这样的格式分页,不过有个问题,就是如果数据量非常大,页数很多,随着limit第一个参数num1偏移量的加大,mysql的查询速度也就变慢
举个栗子 有上百w或千w条数据,我们查询select * from tab1 limit 0,20 和select * from tab1 limit 1111111,20 虽然都是查出20条数据,但查询速度有很大区别,问题就出现在limit的第一个参数上
所以要想查询速度变快,我们需要将limit第一个参数尽量变小
下面简单分解下,借鉴的是同事的思路
比如我有100条数据的用户表user,有uid,uname,pwd 三个字段,其中id是自增主键,连续不连续无所谓,使用快速查询方式的步骤:
$perPage = 10; //假如我要分每页数据条数为10
$dataCount = (select count(*) from user); //查询总数据条数 –当然都是伪代码,重点说明思路
$pageCount = ceil($dataCount/$perPage); //获取总页数
我们正常分页是
获取用户请求的页数page,然后根据page和定义好的perPage来计算offset,从而limit offset,perPage
新的方法是
首先判断如果page等于第一页1,正序正常查询select * from user order by uid asc limit 0,10
然后判断如果page等于最后一页pageCount,
我们首先取余 $mod = $dataCount % $perpage; //查出最后一页数据条数
然后这样查询: select * from user order by uid desc limit 0,$mod; //取出最后一页数据 当然这里查出的数据需要排下序输出到页面
前面两个是预备动作,因为用户点击第一页和最后一页动作很平凡
然后开始说我们的那种比较好的查询方法
正常情况下页面会给我们传page,有时也有perPage,这次我们要加上三个参数currentPage,big,small //当前页,当前页最大主键id,当前页最小主键id
currentPage就是当前页,page是我们想要跳转到的页,然后每次查询出这个页面的数据后,比如我查出10条数据,big是10条数据里的uid最大值,small是最小值
我通常是每次查出数据后用foreach取出这一页id列表,用max,min取最大最小值
foreach($data as v){
$uids[] = $v['uid'];
}
取出主键uid列表后求最大最小值
$big = max($uids);
$small = min($uids);
我们接收到page,currentPage,big,small后
判断page和currentPage的关系
if page>currentPage
select* fromuserwhereuid > big orderbyuid asclimit (page - currentPage - 1)*perpage,perpage;
if page<currentPage
select* fromuserwhereuid < small orderbyuid desclimit (currentPage - page - 1)*perpage,perpage;
也可以用(abs(page-currentPage)-1) * perpage来计算offset
这样的话如果用户访问的两个page差不是很大,offset会非常小,所以查询速度会很快,当然,需要注意下查询出来的数据内容排序问题,拿这里面的例子说,就是第2条sql查出的数据需要倒序下输出到页面。
select * from table where id > 100000 limit 0,10