Redis ZRANGEBYLEX命令的复杂性

时间:2017-12-18 15:20:30

标签: redis time-complexity

根据ZRANGEBYLEX command的文档部分,有以下信息。如果在有序集中存储密钥为零分,则可以使用词典顺序检索以后的密钥。 ZRANGEBYLEX操作复杂度为O(log(N)+M),其中N是总元素数,M是结果集大小。文档中有一些关于字符串比较的信息,但没有说明结构,其中将存储元素。

但经过一些实验和阅读source code之后,当ziplist中的每个元素都与请求匹配时,ZRANGEBYLEX操作可能会进行线性时间搜索。如果是这样,复杂性将比上述更大 - 关于O(N),因为ziplist中的每个元素都将被扫描。

使用gdb进行调试后,在genericZrangebylexCommand函数中实现了ZRANGEBYLEX命令。控制流程在eptr = zzlFirstInLexRange(zl,&range);继续,因此元素检索的主要工作将在zzlFirstInLexRange函数执行。所有namings和跟随控制流都考虑使用ziplist结构,并且所有与输入操作数的比较都是按元素顺序完成的。
在redis存储中插入已知密钥后,通过分析检查内存,似乎ZSET元素实际存储在ziplist - 每字节字节与gauge进行比较确认。

所以问题 - 文档如何出错并在线性出现时传播对数复杂度?或者ZRANGEBYLEX命令可能略有不同?提前谢谢。

1 个答案:

答案 0 :(得分:3)

  

文档如何出错并在线性出现时会传播对数复杂度?

文档在很多情况下都是错误的,但这是一项持续的开源工作,您可以通过存储库(https://github.com/antirez/redis-doc)做出贡献。

  

或者ZRANGEBYLEX命令的工作方式略有不同?

您的结论是正确的,因为排序集搜索操作(无论是否是词典编纂)在使用Ziplists进行编码时表现出线性时间复杂度。

然而

Ziplists是一种优先选择CPU到内存的优化,这意味着它适用于小型集合(即低N值)。它通过配置进行控制(请参阅zset-max-ziplist-entrieszset-max-ziplist-value指令),一旦数据增长到指定的阈值以上,ziplist编码就会转换为skip list

因为ziplists很小(小Ns),所以可以假设它们的复杂性是恒定的,即O(1)。另一方面,由于它们的性质,跳过列表表现出对数搜索时间。 IMO意味着文档的完整性保持不变,因为它提供了最糟糕的案例复杂性。