一、分页查询的那些事儿
咱们做开发的,谁还没写过几个分页查询呢?传统的LIMIT OFFSET方案简单直接,就像去书店买书,跟店员说"我要第100页的10本书",店员就得吭哧吭哧数到第100页再给你拿——效率可想而知。
-- 传统分页查询示例(KingbaseES语法)
SELECT * FROM orders
ORDER BY create_time DESC
LIMIT 10 OFFSET 100; -- 获取第11页数据(每页10条)
当数据量超过10万条时,这种写法就会暴露出致命缺陷:OFFSET越大,数据库越要扫描并丢弃前面的所有行,就像让你从100层高的楼上往下跳,每层都要踩一脚缓冲,最后10层反而最费劲。
二、键集分页的救赎之道
键集分页(Keyset Pagination)的精髓在于:记住上次看到的最后一条记录,下次直接从它后面开始查。这就像书签,不需要知道当前是第几页,只需要记住上次读到哪里。
-- 键集分页示例(假设上次最后一条记录的create_time是'2023-06-20 15:30:00')
SELECT * FROM orders
WHERE create_time < '2023-06-20 15:30:00' -- 关键条件
ORDER BY create_time DESC
LIMIT 10; -- 不需要OFFSET
注意三个要点:
- 排序字段必须有索引(如
create_time上的索引) - WHERE条件必须与ORDER BY方向匹配(这里是
<对应DESC) - 排序字段需唯一(否则需添加主键作为第二排序条件)
三、实战中的进阶技巧
3.1 多字段排序场景
当你的分页需要按多个字段排序时(比如先按分类再按时间),键集分页需要更精细的处理:
-- 多字段键集分页(上次最后记录:category=5, create_time='2023-06-20 15:30:00')
SELECT * FROM products
WHERE (category = 5 AND create_time < '2023-06-20 15:30:00')
OR (category < 5)
ORDER BY category DESC, create_time DESC
LIMIT 10;
3.2 性能对比测试
我们在KingbaseES中构造100万条测试数据,对比两种方案的执行计划:
-- 传统分页(执行时间:1200ms)
EXPLAIN ANALYZE
SELECT * FROM large_table
ORDER BY id
LIMIT 10 OFFSET 999990;
-- 键集分页(执行时间:3ms)
EXPLAIN ANALYZE
SELECT * FROM large_table
WHERE id > 999990
ORDER BY id
LIMIT 10;
键集分页的魔法在于:它可以直接利用索引定位,而不用遍历前面的数据。就像用GPS直接导航到目的地,而不是从起点开始数路口。
四、避坑指南与最佳实践
索引是前提:没有合适的索引,键集分页也会失效。建议为所有排序字段建立复合索引:
CREATE INDEX idx_orders_created ON orders(create_time DESC);边界情况处理:
- 第一页:不需要WHERE条件
- 最后一页:结果不足LIMIT数量时停止加载
- 新增数据可能导致"跳页"(这是特性不是bug)
前端配合:需要将每页最后的记录值传给后端:
// 前端示例(React) const loadNextPage = (lastItem) => { axios.get('/api/orders', { params: { last_time: lastItem.createTime } }) }KingbaseES特有优化:可以利用
FETCH FIRST...ONLY语法:SELECT * FROM orders WHERE create_time < :last_time ORDER BY create_time DESC FETCH FIRST 10 ROWS ONLY; -- KingbaseES特色语法
五、什么时候该用哪种方案
用传统分页:
- 需要显示总页数(需配合COUNT查询)
- 允许随机跳页(如直接跳到第50页)
- 数据量小于1万条时
用键集分页:
- 无限滚动加载(如社交动态)
- 大数据量下的分页(10万条以上)
- 排序字段有索引时
记住:所有技术方案都是权衡的结果。键集分页牺牲了随机访问能力,换来了线性访问的性能飞跃。就像电梯虽然不能停靠所有楼层,但比楼梯快多了不是吗?
六、总结
从LIMIT OFFSET到键集分页的升级,本质上是从"数数式"查询到"导航式"查询的转变。在KingbaseES这样的国产数据库中,合理利用键集分页可以轻松应对百万级数据的分页需求。下次当你看到分页查询变慢时,不妨试试这个"书签大法",可能会收获意想不到的性能提升!
评论