Scan
游标迭代器
大于 2.8.0 版本可用。
时间复杂度:每次调用 O(1)。O(N) 用于完整的迭代,包括足够的命令调用以使光标返回 0。N 是集合内的元素数。
在 Redis 2.8 之前,我们只能使用 keys 命令来查询我们想要的数据,但这个命令存在两个缺点:
此命令没有分页功能,我们只能一次性查询出所有符合条件的 key 值,如果查询结果非常巨大,那么得到的输出信息也会非常多。
keys 命令是遍历查询,因此它的查询时间复杂度是 o(n),所以数据量越大查询时间就越长。
Scan:用于检索当前数据库中所有数据。
HScan:用于检索哈希类型的数据。
SScan:用于检索集合类型中的数据。
ZScan:由于检索有序集合中的数据。
特性
- 它可以完整返回开始到结束检索集合中出现的所有元素,也就是在整个查询过程中如果这些元素没有被删除,且符合检索条件,则一定会被查询出来;
- Scan 可以实现 keys 的匹配功能;
- Scan 是通过游标进行查询的不会导致 Redis 假死;
- Scan 提供了 count 参数,可以规定遍历的数量,但是返回并不是按照规定来的;
- Scan 会把游标返回给客户端,用户客户端继续遍历查询;
- Scan 返回的结果可能会有重复数据,需要客户端去重;
- 单次返回空值且游标不为 0,说明遍历还没结束;
- Scan 可以保证在开始检索之前,被删除的元素一定不会被查询出来;
- 在迭代过程中如果有元素被修改, Scan 不保证能查询出相关的元素。
演示代码
准备数据
1 | /** |
- 一共插入100个string类型。
- 一个set集合100个元素。
- 一个hash集合100个元素。
- 一个zset集合100个元素。
SCAN
scan cursor [MATCH pattern] [COUNT count]
1 | 127.0.0.1:6379> scan 0 match user:* count 5 |
cursor:光标位置,整数值,从 0 开始,到 0 结束,查询结果是空,但游标值不为 0,表示遍历还没结束;
match pattern:正则匹配字段;
count:限定服务器单次遍历的字典槽位数量(约等于),只是对增量式迭代命令的一种提示(hint),并不是查询结果返回的最大数量,它的默认值是 10。
测试结果和预期不太一样,即便设置count为1,但结果不固定。ount 只是限定服务器单次遍历的字典槽位数量(约等于),而不是规定返回结果的 count 值。
HSCAN
hscan key cursor [MATCH pattern] [COUNT count]
1 | 127.0.0.1:6379> HSCAN mUser 0 match user* count 1 |
SSCAN
sscan key cursor [MATCH pattern] [COUNT count]
1 | 127.0.0.1:6379> sscan sUser 0 match 1* count 1 |
ZSCAN
zscan key cursor [MATCH pattern] [COUNT count]
1 | 127.0.0.1:6379> zscan zUser 0 match u* count 10 |
测试代码
- 实现代码发现没有游标,如果查询的数据太多还是redis还是会阻塞。
1 | package cn.z201.redis; |
- Console
1 | [main] 100 |