之前从来没觉得 offset 有什么坑,也没有细想过 mysql 的 offset 的实现原理。
直到这周打算把 4000w+ 的数据热到 redis 中,写了一个脚本, 主要的代码大概如下
1 | from redis import Redis |
开始执行大概下午 6 点左右,然后我就去吃饭逗猫写代码又睡了一觉。
上午 11 点左右来公司发现,才完成了 1000w 左右的数据,内心是崩溃的。。。。。
看了一眼 slow log,一次 Mysql 的查询需要 40s, 然后开始查一些资料找原因,发现 offset/limit 根本无法用到 index 机制,而是读整张表,然后数到需要便宜的位置,所以上面的代码到 1000w 时, mysql 会按照 id 的顺序逐条累加,一直找到第 1000w 的位置(至于为什么不通过 index 来直接找到 id 为 10000000 的数据,原因很简单,id 为 10000000 的数据并不已经代表是第 1000w 条数据,中间有可能会有数据被删除使得 id 非连续)。
找到了原因重写了一把脚本,把 offset 改成 where 就解决了这个问题,然后用了半个小时就跑完了数据- -。
thumbnail