视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
mysql分页时offset过大的Sql优化经验分享
2020-11-09 20:31:32 责编:小采
文档


发现问题

当我们展示一个列表中的内容时,难免会遇到分页问题,因为列表中的内容数量可能很多,但是用户能一次看到的界面大小是有限的,不可能一个界面展示所有的内容,从后端一次性取太多的数据也会给后端造成额外的压力。

通常分页查询的时候会使用这样的语句:

SELECT
*
FROM table
where condition1 = 0
and condition2 = 0
and condition3 = -1
and condition4 = -1
order by id asc
LIMIT 2000 OFFSET 50000

当offset特别大时,这条语句的执行效率会明显减低,而且效率是随着offset的增大而降低的。

原因为:

MySQL并不是跳过offset行,而是取offset+N行,然后返回放弃前offset行,返回N行,当offset特别大,然后单条数据也很大的时候,每次查询需要获取的数据就越多,自然就会很慢。

优化方案:

SELECT
*
FROM table
JOIN
(select id from table
where condition1 = 0
and condition2 = 0
and condition3 = -1
and condition4 = -1
order by id asc
LIMIT 2000 OFFSET 50000)
as tmp using(id)

或者

SELECT a.* FROM table a, 
(select id from table
where condition1 = 0
and condition2 = 0
and condition3 = -1
and condition4 = -1
order by id asc
LIMIT 2000 OFFSET 50000) b 
where a.id = b.id

先获取主键列表,再通过主键查询目标数据,即使offset很大,也是获取了很多的主键,而不是所有的字段数据,相对而言效率会提升很多。

总结

下载本文
显示全文
专题