limit
SELECT * FROM users ORDER BY id LIMIT 10, 20;
从偏移量为10开始,返回20行记录,即第11到第30行记录
如果是limit 20000000 10,那会把前两千万条数据查出来,然后丢弃,然后从第20000001行开始返回10行,性能极低,这就是深度分页问题
深度分页优化:
可以把每次查询到的最大id记录下来,下次从这个id开始继续查:
SELECT * FROM users WHERE id > last_max_id ORDER BY id LIMIT 10;
但这种方案不能往回查,只能一页一页往后查,且查询过程中不能有新增
id不能重复,不然就会陷入死循环,比如一页的10条,ID全是12,last_max_id也为12,那么下一页的查询还是>= 12
覆盖索引 + 子查询:
SELECT * FROM users WHERE id > (SELECT id FROM users ORDER BY id LIMIT 20000000, 1) ORDER BY id LIMIT 10;
子查询在主键索引上查询,不需要回表,得到第20000001的id,然后主查询根据id进行范围查询
使用ES,ES也有深分页问题,但影响比MySQL小点
【【IT老齐074】从76237到753毫秒,海量数据大页码MySQL查询该如何优化?】https://www.bilibili.com/video/BV1PL411g7Vj?vd_source=cae07b1dce3e6abe67fcf72c43031ede
产品上解决问题:
