最近需要从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个数据,其实是全部遍历了的:
那么上面那个例子,如何能减少阅读时间呢?
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