*Redis SORT 命令
对 List、Set 或 Sorted Set 中的元素进行排序,并支持多种高级选项(按外部 key 排序、限制返回数量、存储结果等)。
*语法
SORT key [BY pattern] [LIMIT offset count] [GET pattern [GET pattern ...]] [ASC | DESC] [ALPHA] [STORE destination]
*参数说明
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| key | String | 是 | 要排序的键名(List/Set/Sorted Set) |
| BY | String | 否 | 按外部 key 的值排序,pattern 可用 * 通配符替代元素值 |
| LIMIT | Integer | 否 | offset 和 count,分页 |
| GET | String | 否 | 返回外部 key 的值替代元素本身,可多次使用 |
| ASC/DESC | 标志 | 否 | 升序(默认)/降序 |
| ALPHA | 标志 | 否 | 按字典序排序(默认按数字排序) |
| STORE | String | 否 | 将结果存入新 List |
*返回值
| 条件 | 返回值 |
|---|---|
| 默认 | 排序后的元素数组 |
| STORE | 存入的 element 数量(Integer) |
*时间复杂度
O(N+M*log(M)),N 为 key 中元素数量,M 为返回元素数量。
⚠️ 性能警告:大 key 排序可能阻塞 Redis。大数据量时考虑客户端排序或使用 Sorted Set。
*示例
# List 排序
> RPUSH mylist 3 1 2 5 4
(integer) 5
> SORT mylist
1) "1"
2) "2"
3) "3"
4) "4"
5) "5"
# 降序
> SORT mylist DESC
1) "5"
2) "4"
3) "3"
4) "2"
5) "1"
# 字典序(字符串)
> RPUSH tags "banana" "apple" "cherry"
> SORT tags ALPHA
1) "apple"
2) "banana"
3) "cherry"
# 按外部 key 排序
> LPUSH user_ids 1001 1002 1003
> SET user_score:1001 85
> SET user_score:1002 92
> SET user_score:1003 78
# 按 user_score:* 排序 user_ids
> SORT user_ids BY user_score:*
1) "1003" # score 78
2) "1001" # score 85
3) "1002" # score 92
# 获取用户信息
> SET user_name:1001 "Alice"
> SET user_name:1002 "Bob"
> SET user_name:1003 "Charlie"
> SORT user_ids BY user_score:* GET user_name:*
1) "Charlie"
2) "Alice"
3) "Bob"
# 分页
> SORT user_ids BY user_score:* LIMIT 0 2
1) "1003"
2) "1001"
# 存储结果
> SORT user_ids BY user_score:* STORE sorted_users
(integer) 3
> LRANGE sorted_users 0 -1
1) "1003"
2) "1001"
3) "1002"
*常见错误
- BY 的 key 不存在:按默认顺序排序(相当于没有 BY)。
- 数字 vs 字符串:默认按数字排序,字符串排序必须加 ALPHA,否则报错。
- 大 key 阻塞:百万元素的 List 排序可能阻塞 Redis 数秒。
*最佳实践
- 外部排序缓存:复杂排序场景用 SORT ... STORE 将结果缓存到 List,查询时直接 LRANGE。
- 优先用 Sorted Set:需要频繁排序的场景,数据入 Sorted Set(score 为排序字段),避免每次 SORT。
- 分页限制:大数据量排序必用 LIMIT,避免返回过多数据。
- ALPHA 注意:字符串排序必须加 ALPHA,否则数字解析失败会报错。
*FAQ
Q: SORT 会修改原 key 吗? A: 不会。除非使用 STORE,否则原 key 不变。
Q: BY 的 pattern 中 * 怎么工作?
A: SORT 遍历 key 的每个元素,将 * 替换为元素值,查找对应的 BY key。如元素为 1001,user_score:* 变成 user_score:1001。
Q: GET 可以用 # 吗?
A: 可以。GET # 返回元素本身(默认行为),配合其他 GET 可同时返回元素和外部数据。
Q: SORT 和 Sorted Set 怎么选择? A: 数据固定且排序复杂(多字段)用 SORT + STORE 缓存;数据动态变化或排序简单用 Sorted Set 实时排序。