You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

非连续UUID主键表如何查询指定id后按inserted_at排序的n条数据

解法

我们采用**键集分页(Keyset Pagination)**方案实现该需求,该方案性能远高于OFFSET分页,同时能避免时间重复导致的分页错乱问题:

1. 单查询写法(CTE实现)

假设你需要按inserted_at倒序排序(越新的记录越靠前),取目标id之后的10条(n=10)记录,写法如下:

WITH target_row AS (
    -- 先取出目标id对应的时间和id值
    SELECT inserted_at, id 
    FROM users 
    WHERE id = '替换为你的目标uuid值'
)
SELECT u.*
FROM users u, target_row t
WHERE 
    -- 时间早于目标行
    u.inserted_at < t.inserted_at 
    -- 时间相同的情况下,id小于目标行(保证排序唯一)
    OR (u.inserted_at = t.inserted_at AND u.id < t.id)
-- 排序规则必须和WHERE中的比较逻辑对应
ORDER BY u.inserted_at DESC, u.id DESC
LIMIT 10; -- 替换为你需要的n值

如果需要按inserted_at正序排序(越晚新增的记录越靠后),只需要反转比较符和排序方向即可:

WITH target_row AS (
    SELECT inserted_at, id 
    FROM users 
    WHERE id = '替换为你的目标uuid值'
)
SELECT u.*
FROM users u, target_row t
WHERE 
    u.inserted_at > t.inserted_at 
    OR (u.inserted_at = t.inserted_at AND u.id > t.id)
ORDER BY u.inserted_at ASC, u.id ASC
LIMIT 10;

2. 拆分为两次查询写法

如果你不想使用CTE,也可以拆分为两次单独查询,效果完全一致:
第一步先查询目标行的时间和id:

SELECT inserted_at, id FROM users WHERE id = '替换为你的目标uuid值';

假设查询得到的时间为'2024-05-01 14:30:00+08',id为'a1b2c3d4-5678-90ef-ghij-klmnopqrstuv',第二步查询后续n条记录:

SELECT * FROM users
WHERE 
    inserted_at < '2024-05-01 14:30:00+08' 
    OR (inserted_at = '2024-05-01 14:30:00+08' AND id < 'a1b2c3d4-5678-90ef-ghij-klmnopqrstuv')
ORDER BY inserted_at DESC, id DESC
LIMIT 10;

优化建议

给inserted_at和id创建匹配排序方向的联合索引,可大幅提升查询性能,适配大数据量场景:

-- 适配倒序排序的索引
CREATE INDEX idx_users_inserted_at_id_desc ON users (inserted_at DESC, id DESC);
-- 如果用正序排序,可以创建对应索引
CREATE INDEX idx_users_inserted_at_id_asc ON users (inserted_at ASC, id ASC);

内容的提问来源于stack exchange,提问作者malobre

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 18:36:03