zrange 是 redis sorted set 中的一个指令,最近线上有个查询从 mysql 切到了 redis,在使用 mysql 的 offset、limit 查询时,当 offset 过大时会有性能问题,不禁疑惑,用 redis 的 zrange 是否会有类似的问题呢?
看了下 redis sorted set 实现,当一个 sorted set 的元素数量比较多,或者集合中的成员是比较长的字符串时,底层会使用跳表来实现,关于跳表是什么不再赘述,网上相关文章很多,可以参考下。http://redisdoc.com/sorted_set/zrange.html 上说 zrange 的复杂度是 O(log(N)+M), N 为有序集的基数,而 M 为结果集的基数。为什么是这个复杂度呢?
ZRANGE key start stop [WITHSCORES],zrange 就是返回有序集 key 中,指定区间内的成员,而跳表中的元素最下面的一层是有序的(上面的几层就是跳表的索引),按照分数排序,我们只要找出 start 代表的元素,然后向前或者向后遍历 M 次拉出所有数据即可,而找出 start 代表的元素,其实就是在跳表中找一个元素的时间复杂度。跳表中每个节点每一层都会保存到下一个节点的跨度,在寻找过程中可以根据跨度和来求当前的排名,所以查找过程是 O(log(N) 过程,加上遍历 M 个元素,就是 O(log(N)+M),所以 redis 的 zrange 不会像 mysql 的 offset 有比较严重的性能问题。