MySQL 中如何解决深度分页的问题?

Sherwin.Wei Lv7

MySQL 中如何解决深度分页的问题?

回答重点

优化方式可以有三种:

1)子查询

比如 select * from mianshiya where name = ’yupi‘ limit 99999990,10; 这样的一条查询语句,可以优化成:

1
2
3
4
5
select * from mianshiya where 
name = 'yupi'
and id >=
(select id from mianshiya where name = 'yupi' order by id limit 999999901)
order by id limit 10;

name 有索引的情况下,这样的查询直接扫描 name 的二级索引,二级索引的数据量少,且在子查询中能直接得到 id 不需要回表。将子查询得到的 id 再去主键索引查询,速度很快,数据量也小。

如果直接扫描主键索引的话,数据量就比较大,因为主键索引包含全部的数据。

当然上面的 SQL 改成 Join 也行,本质上是一样的。

1
2
3
4
select * from mianshiya 
inner join
(select id from mianshiya where name = 'yupi' order by id limit 9999999010)
as mianshiya1 on mianshiya.id = mianshiya1.id

2)记录 id

每次分页都返回当前的最大 id ,然后下次查询的时候,带上这个 id,就可以利用 id > maxid 过滤了。

这种查询仅适合连续查询的情况,如果跳页的话就不生效了。

3)elasticsearch

可以考虑用搜索引擎来解决这个问题,不过 es 也会有深度分页的问题,所以如果对 es 不熟,面试就不要这样答了,防止面试官问 es 的深度分页如何解决。

扩展知识

深度分页

所谓的深度分页是指数据量很大的时候,按照分页访问后面的数据,例如 limit 99999990,10,这会使得数据库扫描前面的 99999990 条数据,才能得到最终的 10 条数据,大批量的扫描数据会增加数据库的负载,影响性能。

Comments
On this page
MySQL 中如何解决深度分页的问题?