延迟游标又称为基于基于键集的分页,是一种深度分页优化技术,它通过依赖排序字段(通常是唯一且有序的字段,如主键id
或时间戳created_at
)来实现高效分页查询。
什么是延迟游标分页?
延迟游标分页的核心思想是根据当前页的最后一条记录的标识,直接查询下一页的记录,而非依赖offset
来跳过大量的记录(仍然会遍历一遍)。
与传统的LIMIT ... OFFSET ...
分页不同,延迟游标分页不需要跳过前面多余的行,因此可以有效解决因深度分页而导致的查询效率急剧下降的问题。
传统分页与延迟游标分页的区别
传统分页:使用LIMIT
和OFFSET
,如:
select * from products order by created_at limit 20 offset 1000;
这条sql语句会跳过前1000条记录,返回第10001条到第1020条记录,结果按created_at
排序。当offset增大时,分页越深,查询越慢。
延迟游标分页:
select * from products where created_at > 'last_timestamp' order by created_at limit 20;
其中last_timestamp
是上一页最后一条记录的created_at
时间戳。记录上一页最后一条记录的好处是,无论分页大小为多少,数据库只需要从上一次查询结束的地方开始查询即可,不需要跳过大量的记录,性能稳定。
为什么延迟游标分页可以在分页查询时记住上一页的最后一条记录?
延迟游标分页能够记住上一页的最后一条记录,并在此基础上进行查询,是因为它依赖于数据库表中的某个有序且唯一的字段(通常是id
或created_at
)。
因此有序且唯一的查询字段在查询结果中是有明确顺序的,因此可以根据上一次页面的查询结果,来将该字段作为'游标',下一次查询时从游标处开始查找下一页的记录即可。
优点和缺点:
优点:高效分页,不会随着分页深度的增加导致查询速度变慢,避免了大量不必要的查询。
缺点:延迟游标分页要求查询数据必须基于某个有序字段,且无法实现随机跳转,无法直接跳转到具体的页面。
针对于深度分页查询中,查询字段不是唯一且有序的情况时,无法使用延迟游标分页时,可以对字段建立索引进行查询或者为每条记录生成一个全局唯一标识(UUID),以此来进行延迟游标分页。