首页/数据/Redis 进阶速查/SORT 的复杂度与用法约束
性能与排障129 条

SORT 的复杂度与用法约束

SORT 默认 O(N log N),带 BY/GET 外部键引用时开销进一步放大;大集合排序建议迁移到 zset 或离线计算。

Redis 进阶速查数据更新于 2026-10-13

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 每次都全量处理。

易错点

  • 把大集合丢给 SORT 做临时排行:全量取出加排序,主线程长时间被占用,CPU 尖峰常见于此
  • 以为加 LIMIT 就能省成本:LIMIT 只限制返回条数,排序仍是全量
  • 字符串排序忘记 ALPHA:非数值元素被当 0,排序结果错得没有规律
  • SORT 配合 STORE 直接落到业务键上:覆盖原有数据,还顺手造出一个新的大 key
  • 周期性排行需求每次现算:成本重复支出,应预计算进 zset 后查询

数据来源与参考

  • Redis 官方文档:SORT 命令说明
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌