问题描述

这个问题让我想起 Transient RSS feeds in wp_options not removed automatically?

瞬变应该过期并被删除。但是,我看到处理的唯一方法是暂时过期并被请求,然后在请求期间被删除。

如果瞬时过期但从未请求过吗?从食品法典的描述我认为某种垃圾收集是隐含的。现在我不太确定,找不到任何执行这样的代码。

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

最佳解决方案

他们现在是

从 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);
    }
}

次佳解决方案

通过 re-wording 和 re-formatting 将一些评论从讨论中移到答案中。

基本上,它归结到的是,除非你有一个超级极端的情况,他们真的不需要是”garbage collected” 。如果你从来没有拿过他们,那么无论他们在哪里,都没关系。

参见,默认情况下,瞬态存储在选项表中。在基础安装中,选项表中可能有 100 个条目。每个临时增加两个条目,但是即使有数千个条目,它们也不会影响网站速度,因为它们不被自动加载。

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

从数据库的角度来看,options 表具有选项 ID 和选项名称的索引。瞬态总是基于名称 (键) 加载,因此它们的查找始终是单个唯一键值上的简单选择。因此,查找是 O(log(n)),并且超快。使用日志 (n) 的 Big-O,您必须进入数百万和数百万行才能变得显而易见。坦率地说,查询的设置和拆卸的开销以及实际的数据传输更长。查询本身通过比较基本上运行在 zero-time 中。所以只需要额外使用的行就不会影响任何东西,只能使用额外的磁盘空间。

数据库中的索引是 deep-read 的一种想法,对于不了解幕后情况的人来说,这些想法是没有意义的。数据库设计用于快速数据检索,从头开始,可以处理这种事情没有问题。这是一个很好的阅读:http://en.wikipedia.org/wiki/Index_(database)

现在,以最明显的方式 (调用 SQL DELETE) 清理它们并不会从数据库中删除它们。它只是从索引中删除它们,并将该行标记为”deleted” 。再次,这只是数据库的工作原理。要实际清除磁盘空间,您必须继续,然后执行一个 OPTIMIZE TABLE,这不是一个快速的操作。这需要时间。可能更多的时间比它的价值。总共可以节省 CPU 时间,这可能还不够。

如果您有某种情况导致连续插入未被使用的新瞬变,则需要找到基础问题。什么是插入这些瞬变?他们在使用更改或变更的密钥吗?如果是这样,那么导致这个的插件或代码应该是固定的,基本上不这样做。这将会更有帮助,因为没有正确创建它们的代码可能不是检索它们,因此做的更多的工作。

另一方面,可能存在像每个帖子这样的事物创建瞬变的情况。这可能是完全可以接受的。我自己在证监会做这个,以存储来自 Facebook 的意见。每个帖子都有一个潜在的瞬态关联,这意味着每个帖子有两个额外的行。如果你有 10k 的帖子,那么在选项表中最终会有 20k 行。这不错还是缓慢,因为数据库真的很在乎,100 行和 20,000 行之间的差别很小。这都是索引。它的速度很快。 Sub-sub-milliseconds 。

当你开始上百万行时,我会担心。当选项表的大小增加到数百兆字节以上时,我会很关心,仔细看看。但一般而言,除极端情况外,这不是一个问题。任何比像大型新闻网站那样小的东西,数以万计的帖子,这当然不是问题。而对于任何足够大的网站来说,这是一个问题,您应该使用某种外部对象缓存,而在这种情况下,瞬态会自动存储在数据库中而不是数据库中。

第三种解决方案

奥托 – 我不能不同意你的意见。问题是,最终所有这些瞬间,桌子的大小变得可笑。它不会使数百万行陷入死锁。我正在处理一个超过 130k 行的选项表,并定期挂起。因为值字段是一个大的文本类型,甚至只寻找”autoload” 行成为一个噩梦的表现。这些值字段与行数据的其余部分分开存储。即使它在逻辑上是同一个表的一部分,连接必须发生,以便拉出你想要的行。加入现在永远是因为您需要的数据遍布磁盘上的所有位置。 Profiling(使用 jet profiler for mysql) 证明了这一点。

将 auto-load 添加到群集密钥可能有助于解决此问题。自动加载描述中的集群 (例如 ID ASC) 将允许所有自动加载行首先在磁盘上聚集在一起。即使我仍然认为你从数据库的角度来看待一个巨大的压力。

就个人而言,我认为这个系统的设计是一个很好的选择。选项表似乎已经变成了一般的 catch-all 很多东西。如果值字段足够小以便与 rowdata 的其余部分包含在同一页面上,那么就可以了,并且可以有效地建立索引。不幸的是,情况并非如此。谁设计这个需要回到 DB101 课堂。

参考文献

注:本文内容整合自 Google/Baidu/Bing 辅助翻译的英文资料结果。如果您对结果不满意,可以加入我们改善翻译效果:薇晓朵技术论坛。