【问题标题】:what is the Time complexity of redis del command?redis del 命令的时间复杂度是多少?
【发布时间】:2017-03-23 11:10:03
【问题描述】:

del 命令的官方文档:

时间复杂度:O(N),其中 N 是要移除的键的数量。当要删除的键包含字符串以外的值时,该键的单个复杂度为 O(M),其中 M 是列表、集合、排序集或散列中元素的数量。删除包含字符串值的单个键是 O(1)。

为什么?我认为即使key引用了一个复杂类型,del的时间复杂度应该一直是O(1)。redis db找到key的hash值并移除它,这个操作的时间复杂度是O(1)。

在redis源代码中,“del命令”的实现如下:

void delCommand(client *c) {
    int deleted = 0, j;

    for (j = 1; j < c->argc; j++) {
        expireIfNeeded(c->db,c->argv[j]);
        if (dbDelete(c->db,c->argv[j])) {
            signalModifiedKey(c->db,c->argv[j]);
            notifyKeyspaceEvent(NOTIFY_GENERIC,
                "del",c->argv[j],c->db->id);
            server.dirty++;
            deleted++;
        }
    }
    addReplyLongLong(c,deleted);
}

如上,删除1个key的复杂度应该是O(1),不管是什么复杂类型。

【问题讨论】:

  • 这个问题很好,它真正的意思是'为什么当键是复杂的数据结构时,DEL 的复杂性被列为 O(n)。我也希望它是 O(1),sigh .

标签: redis


【解决方案1】:

删除 1 个键的复杂度为 O(1)。删除 5keys 的复杂度为 O(5) (如文档中所述 -> O(N) )。但是如果键引用了一个复杂类型,比如一个列表,那么 Redis 也需要删除该列表中的所有内容,而不仅仅是引用该列表的键。如果它只是删除键,列表仍将使用内存。

Redis 中的列表、哈希、集合等不是作为一个“字符串”实现的,它会被反序列化、修改、序列化并再次存储(这将不具有性能并且使用更多内存),而是作为高度优化的结构.为了获得 Redis 提供的性能和小内存打印,有一个“权衡”,即删除操作并不总是 O(N),而是 O(N*M)。

【讨论】:

  • 我的观点是:每个redis对象都有一个refcount属性,当key为del时,value对象的refcount减1,当refcount为0时,value内存会自动释放。你确定redis也需要删除该列表中的所有内容吗?而从redis源代码中,我没有在那个列表中找到del的操作。谢谢!
  • 对不起。当我继续阅读 redis 源代码时,我意识到,当列表键为 del 时,Redis 确实需要删除该列表中的所有内容。对了,非常感谢!
猜你喜欢
  • 1970-01-01
  • 2018-11-24
  • 2014-05-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-09
  • 2020-07-01
  • 2021-08-03
相关资源
最近更新 更多