是否对瞬变进行垃圾收集?

时间:2011-01-09 作者:Rarst

这个问题让我思考Transient RSS feeds in wp_options not removed automatically?

瞬态应该过期并被删除。然而,我看到这种处理的唯一方式是当瞬态过期并被请求时,然后在请求期间将其删除。

如果transient已过期,但此后再也没有请求,该怎么办?根据Codex中的描述,我认为暗示了某种垃圾收集。现在我不太确定,也找不到任何执行这种操作的代码。

那么它会永远卡在数据库中吗?

3 个回复
最合适的回答,由SO网友:Rarst 整理而成

现在,从WordPress 3.7开始,数据库升级时会删除过期瞬态,请参阅#20316

如果有人不能给我其他的答案,那么看起来瞬变毕竟不是垃圾收集的。更糟糕的是,与选项不同,它们不能保证存储在数据库中。所以,并没有可靠的方法来获取所有瞬态的列表,以检查它们是否过期。

如果数据库用于存储,则执行垃圾收集的一些临时代码:

add_action( \'wp_scheduled_delete\', \'delete_expired_db_transients\' );

function delete_expired_db_transients() {

    global $wpdb, $_wp_using_ext_object_cache;

    if( $_wp_using_ext_object_cache )
        return;

    $time = isset ( $_SERVER[\'REQUEST_TIME\'] ) ? (int)$_SERVER[\'REQUEST_TIME\'] : time() ;
    $expired = $wpdb->get_col( "SELECT option_name FROM {$wpdb->options} WHERE option_name LIKE \'_transient_timeout%\' AND option_value < {$time};" );

    foreach( $expired as $transient ) {

        $key = str_replace(\'_transient_timeout_\', \'\', $transient);
        delete_transient($key);
    }
}

SO网友:Otto

将讨论中的一些评论转化为答案,并重新措辞和格式。。

基本上,归结起来就是,除非你有一个极端的情况,否则它们真的不需要被“垃圾收集”。如果你从不去拿它们,那么它们在不在也没关系。

请参见,瞬态默认存储在选项表中。在基本安装中,选项表中可能有100个条目。每个瞬变添加两个以上的条目,但即使您有数千个条目,它们也不会影响站点速度,因为它们不是自动加载的。

启动时,WordPress会将选项加载到内存中,但它只加载启用了自动加载标志的选项。瞬变不会得到这个,所以也不会加载到内存中。只有后来实际使用的瞬态才会产生成本。

从数据库的角度来看,选项表在选项Id和选项名称上都有索引。瞬变总是基于名称(键)加载的,因此对它们的查找总是简单地选择一个唯一的键值。因此,查找是O(log(n)),速度非常快。对于log(n)的一个大O,您必须进入数百万行,才能看到它。坦率地说,查询的设置和拆卸以及实际数据传输的开销要长得多。通过比较,查询本身的运行时间基本为零。因此,只需拥有额外的未使用行,除了使用额外的磁盘空间之外,不会产生任何影响。

在数据库中建立索引是一种深度阅读的想法,对于那些还没有真正了解幕后情况的人来说是没有意义的。数据库是为快速数据检索而设计的,从头开始,可以毫无问题地处理这类事情。这本书读得很好:http://en.wikipedia.org/wiki/Index_(database)

现在,最明显的清理方式(对它们调用SQL DELETE)实际上并没有从数据库中删除它们。它只是将它们从索引中删除,并将该行标记为“已删除”。同样,这就是数据库的工作方式。要真正清理磁盘空间,您必须继续,然后再执行一个优化表,这不是一个快速的操作。这需要时间。可能要花更多的时间。总的来说,这可能还不足以节省CPU时间。

如果您遇到了导致不断插入未使用的新瞬态的情况,那么您需要找到潜在的问题。什么是插入这些瞬态?他们使用的是变化键还是变异键?如果是这样,那么导致这种情况的插件或代码应该被修复为基本上不这样做。这将更有帮助,因为没有正确创建它们的代码可能也没有检索它们,因此需要做的工作比必须做的更多。

另一方面,可能存在这样的情况,即为每个帖子创建瞬态。这可能确实是完全可以接受的。我自己在证监会这样做,以存储来自Facebook的评论。每个立柱都有一个与之相关的潜在瞬态,这意味着每个立柱多出两行。如果有10k个帖子,那么选项表中最终会有20k行。这并不坏,也不慢,因为就数据库真正关心的问题而言,100行和20000行之间的差别很小。都被索引了。真是太快了。亚-亚毫秒。

当你开始进入数百万行时,我会担心的。当选项表的大小增加到数百兆字节以上时,我会非常担心,仔细看看。但一般来说,除了极端情况外,这不是一个问题。这当然不是一个比大型新闻网站(拥有数十万条帖子)更小的问题。对于任何足以使其成为问题的站点,您应该使用某种外部对象缓存,在这种情况下,瞬态会自动存储在那里,而不是数据库中。

SO网友:myke

奥托——我完全不同意你的意见。问题是,最终在所有这些瞬态中,表的大小变得荒谬。不需要数百万行就可以停滞不前。我目前正在处理一个选项表,它有超过130k行,并且经常挂起。由于值字段是一种大型文本类型,即使只查找“自动加载”行也会成为性能的噩梦。这些值字段与行数据的其余部分分开存储。即使它在逻辑上是同一个表的一部分,也必须进行连接才能提取所需的行。连接现在需要很长时间,因为您需要的数据分布在磁盘上的所有位置。分析(使用jet profiler for mysql)已经证明了这一点。

向集群键添加自动加载可能有助于解决此问题。在Autoload Desc(例如ID ASC)上进行集群将允许所有自动加载行首先在磁盘上聚集在一起。即使如此,我认为你从DB的角度来看是一个巨大的压力。

我个人认为这个系统的设计很古怪。选项表似乎已成为许多事情的总括。如果值字段足够小,可以包含在与其余行数据相同的页面上,并且可以有效地建立索引,那么这很好。不幸的是,情况并非如此。无论是谁设计的,都需要返回到DB101类。

结束

相关推荐

如何获取我在Add_Options_Page中为我的页眉指定的标题

我有add_options_page(\'Post Products Settings\', \'Post Products Settings\', \'administrator\', \'pp_settings\', \'pp_settings_page\'); 无论如何,我可以得到在第一个参数中指定的内容,以便在我的页眉中使用?我知道我可以硬编码,但只是好奇