SORT 的复杂度与约束
SORT 会取出集合的全部元素再排序,复杂度为 O(N+M log M),其中 N 是元素总数、M 是返回条数;加了 BY 或 GET 之后还会对每个元素额外做一次外部键查找。它适合小规模的一次性排序,凡是周期性排行榜需求,都应该用 zset 提前维护顺序,把排序成本摊到写入时。
基本信息
| 复杂度 | O(N+M log M) |
|---|---|
| 默认口径 | 按数值排序,字符串必须加 ALPHA |
| 扩展选项 | BY/GET 引用其他键,STORE 把结果落库 |
| 只读变体 | SORT_RO(Redis 7.0 起) |
| 观测 | SLOWLOG、INFO commandstats |
| 推荐替代 | zset 维护顺序,查询走 ZRANGE |
典型使用场景
- 排行榜类需求:不要每次现算,用 zset 的 score 维护顺序
- 小规模排序:元素少时 SORT 依然方便,用 LIMIT 限制返回量
- 报表与导出:放到从库或离线执行,避免压主库
- 排查 CPU 尖峰:慢查询日志里出现 SORT,复查是不是大集合临时排序
- 只读场景:用 SORT_RO 替代,语义相同但不作为写命令处理
最小示例
最小示例
redis-cli SORT big:list LIMIT 0 10 ALPHA # 只取前 10 条,别全量排
redis-cli SORT big:list BY weight_*->score GET #->name # 按外部 hash 字段排序取值
redis-cli SLOWLOG GET 10 # 确认 SORT 是否进了慢查询
redis-cli INFO commandstats | grep -i sort # 看调用次数与耗时
redis-cli SORT_RO big:list LIMIT 0 10 # 只读变体(7.0 起)
redis-cli ZRANGE rank:board 0 9 WITHSCORES # 用 zset 替代临时排序代价与替代
| 做法 | 代价 | 替代方案 |
|---|---|---|
| 对 N 个元素排序 | 主线程占用随 N 增长 | 用 zset 提前维护顺序 |
| BY/GET 引用外部键 | 每个元素一次额外查找 | 把权重冗余到 zset 的 score |
| SORT 配合 STORE | 写出新键,可能又造一个大 key | 落库前评估体积并设置 TTL |
| 周期性排行需求 | 每次都全量重排,成本重复支出 | 预计算写 zset,查询走范围接口 |
SORT 的成本主要在「取出并排序全部元素」,加 LIMIT 只减少返回条数,不减少排序工作量。
字符串排序必须显式加 ALPHA,否则元素会被当数值处理,非数值元素按 0 参与比较,顺序会毫无规律。
zset 是排序需求的正解:写入与更新是 O(log N),范围查询只取需要的条数,不像 SORT 每次都全量处理。