mysql 分页读为什么越来越慢

最近需要从mysql的table里根据索引一页一页(一页有1000条数据)的读数据出来,但是如果把log打印出来如下:


2019-04-24 16:19:29.398 DEBUG 20367 --- [eduler_Worker-1] c.z.e.p.batch.reader.ArticleItemReader   : Reading page 0
2019-04-24 16:19:29.426  INFO 20367 --- [eduler_Worker-1] 
2019-04-24 16:19:29.789 DEBUG 20367 --- [eduler_Worker-1] c.z.e.p.batch.reader.ArticleItemReader   : Reading page 1
2019-04-24 16:19:29.912 DEBUG 20367 --- [eduler_Worker-1] c.z.e.p.batch.reader.ArticleItemReader   : Reading page 2
2019-04-24 16:19:30.026 DEBUG 20367 --- [eduler_Worker-1] c.z.e.p.batch.reader.ArticleItemReader   : Reading page 3
2019-04-24 16:19:30.156 DEBUG 20367 --- [eduler_Worker-1] c.z.e.p.batch.reader.ArticleItemReader   : Reading page 4
...
2019-04-24 16:24:46.403 DEBUG 20367 --- [eduler_Worker-1] c.z.e.p.batch.reader.ArticleItemReader   : Reading page 388
2019-04-24 16:24:48.250 DEBUG 20367 --- [eduler_Worker-1] c.z.e.p.batch.reader.ArticleItemReader   : Reading page 389
2019-04-24 16:24:49.759 DEBUG 20367 --- [eduler_Worker-1] c.z.e.p.batch.reader.ArticleItemReader   : Reading page 390

可以看出,当阅读量打到300万以后,每1000条数据阅读花掉的时间打到了1.5秒左右。
这个是什么原因呢?原来,我们以为的是,有索引之后,读取到某页,直接去那个页就行,其实不是。其实是按顺序读取所有,然后取某一个页出来。
比如,脚本是这样:

SELECT  *
FROM    news
WHERE   cat_id = 4
ORDER BY
id DESC
LIMIT   150000, 10

这个任务可以重新像这样:走过去的150010行的id顺序,返回第10人这意味着虽然我们只需要10条记录,但我们仍需要计算前150,000条记录。

假如数据长这样:

数据和索引

如果我们要找第10个数据,其实是全部遍历了的:


image.png

那么上面那个例子,如何能减少阅读时间呢?

SELECT  l.id, value
FROM    (
SELECT  id
FROM    t_limit
ORDER BY
id
LIMIT 150000, 10
) o
JOIN    t_limit l
ON      l.id = o.id
ORDER BY
l.id

你可能感兴趣的:(mysql 分页读为什么越来越慢)