梗概
- 按指定列(通常是ID)排序表,用一个值来记录当前遍历到的值,下次用where选取这个值,从这个值开始遍历
- 这个值需要有索引,这样where会非常快
特点
这个方案有个特点:下次遍历必须知道上次遍历的最后一个id的值,也就是前后遍历形成了一个依赖链,这将导致无法实现遍历行为之间的并行操作
示例
select * from a where id > 0 order by id limit 10000;假设上一次查询得到的结果集中,最后一条数据的id为10001
select * from a where id > 10001 order by id limit 10000;
好,既然没用到索引,那就带上索引遍历。 类似的查询效果,由于where条件中的id字段有索引,对于比较靠后的数据,查询性能将会轻松提升很多(有人说是百倍左右,我没测试过就不说具体多少了) 那初步的优化方案就很容易想到了,id有索引,而且是自增的,就从id=1开始遍历,结果集以id升序排列,然后根据结果集最后一条数据的id,继续下一次遍历,依此类推,直到遍历完成
nestJS示例
示例
do {
// 查询索引
askIndexList = await askIndexRepo.find({
select: ["id"],
where: { id: LessThan(beginId) },
order: { id: "DESC" },
take: chunkSize,
});
if (!askIndexList.length) continue;
beginId = askIndexList[askIndexList.length - 1].id;
await write(askIndexList.map((item) => encrypt(item.id)).join("\n"));
await write("\n");
} while (askIndexList.length);