【问题标题】:Redis ZRANGEBYLEX command complexityRedis ZRANGEBYLEX 命令复杂度
【发布时间】:2017-12-19 01:47:42
【问题描述】:

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

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

用gdb调试后,genericZrangebylexCommand函数中实现了ZRANGEBYLEX命令是干净的。控制流在eptr = zzlFirstInLexRange(zl,&range); 继续,因此元素检索的主要工作将在zzlFirstInLexRange 函数中执行。所有命名和以下控制流程都认为使用了ziplist 结构,并且与输入操作数的所有比较都是逐个元素按顺序完成的。
在redis store中插入众所周知的keys后通过分析检查内存,ZSET元素似乎真的存储在ziplist - byte-per-byte与gauge的比较确认它。

所以问题 - 文档如何出错并传播对数复杂性出现线性的地方?或者 ZRANGEBYLEX 命令的工作方式可能略有不同?提前致谢。

【问题讨论】:

    标签: redis time-complexity


    【解决方案1】:

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

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

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

    您的结论是正确的,因为当使用 Ziplist 对其进行编码时,Sorted Set 搜索操作(无论是否按字典顺序)都表现出线性时间复杂度。

    但是。

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

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

    【讨论】:

    • 谢谢,这很有用!遗憾的是,ZRANGEBYLEX 不适用于不同的分数。
    猜你喜欢
    • 2019-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多