limit offset,N 当offset非常大时,效率极低。
原因是:mysql并不是跳过offset行,然后单取N行。而是取offset+N行。
返回时,放弃前offset行,返回N行。效率较低,当offset越大是,效率越低。
优化方式:
1. 非技术手段限制分页,比如百度翻页一般不会超过70页,谷歌不会超过40页。
// 计算总的记录数 $total = ... // 定义每页显示数量 $perpage = 10; // 计算总的页数 $pagecount = min(ceil($total/$perpage),70);
2. 不用offset,用条件查询。
$sql = "select * from user limit 10,10"; // 转换成 $sql = "select * from user where id>10 limit 10";
缺点:如果数据有被删除,则取出的数据结果会不一致。
解决方案:
数据不进行物理删除(可逻辑删除)最终在页面上显示数据时,逻辑删除的条目不显示即可。
一般来说,大网站的数据都是不物理删除的,只做逻辑删除,比如is_delete=1
3. 如果非要物理删除,还要用offset精确查询,还不限制用户分页,怎么办?
我们现在必须要查,则只查索引,不查数据,得到id,再用id去查具体条目,这种技巧就是延迟索引。
第一步:取出数据的id
$sql = "select * from user limit 10000,10"; // 没有用到索引 // 转换成 $sql = "select id from user limit 10000,10"; // 用到索引覆盖
第二步:根据取出id再查具体的数据,因为使用id查询比较快,因为id是主键。
因此使用一个连接查询,就可以,我们使用内连接。inner join / left join / right join