1.深度分页情景

select * from table limit 0,10;
select * from table limit 1000,10;

这两条语句查询时间在毫秒级完成。

select * from table limit 3000000,10;

你可能没想到,这条语句执行之间在5s左右。
为什么相差这么大?
可能mysql并没有你想的那么智能,比如你要查询 300w开始后面10条数据;mysql会读取300w加10条这么多的数据,只不过 过滤后返回最后10条而已!!!

2.解决办法

2.1 业务逻辑上解决

此方法简单粗暴,就是不允许查看这么靠后的数据,比如百度就是这样的,最多翻到76页就不让你翻了,这种方式就是从业务上解决。
百度搜索业务处理

2.2 只能查询上下页

在查询下一页时把上一页的 max id 作为参数传递给客户端程序,然后sql就改成了

select * from table where id > 3000000 limit 10;

这条语句执行也是在毫秒级完成的,id>300w其实就是让mysql直接跳到这里了,不用依次在扫描全面所有的行。如果你的table的主键id是自增的,并且中间没有删除和断点,那么还有一种方式,比如100页的10条数据。

select * from table where id > 100 * 10 limit 10;

淘宝网的处理方式

2.3 延迟关联

我们在来分析一下这条语句为什么慢,慢在哪里。

select * from table limit 3000000,10;

玄机就处在这个 里面,这个表除了id主键肯定还有其他字段 比如 name、age 之类的,因为select 所以mysql在沿着id主键走的时候要回行拿数据,走一下拿一下数据。
如果把语句改成

select id from table limit 3000000,10;

你会发现时间缩短了一半;然后我们在拿id分别去取10条数据就行了;语句就改成这样了:

select table.* from table inner join ( select id from table limit 3000000,10 ) as tmp on tmp.id=table.id;

这三种方法最先考虑第一种其次第二种,第三种是别无选择

最后修改:2021 年 09 月 22 日 05 : 21 PM
如果觉得我的文章对你有用,请随意赞赏