这个问题让我想到wp_options中的瞬态RSS提要不会自动删除吗?
瞬态应该过期并被删除。但是,我看到此处理的唯一方法是当瞬变过期并被请求时,然后在请求期间将其删除。
如果瞬变已过期但之后又没有请求怎么办?从法典中的描述,我认为这意味着某种垃圾回收。现在,我不确定,也找不到执行此操作的任何代码。
那么它将永远永远停留在数据库中吗?
这个问题让我想到wp_options中的瞬态RSS提要不会自动删除吗?
瞬态应该过期并被删除。但是,我看到此处理的唯一方法是当瞬变过期并被请求时,然后在请求期间将其删除。
如果瞬变已过期但之后又没有请求怎么办?从法典中的描述,我认为这意味着某种垃圾回收。现在,我不确定,也找不到执行此操作的任何代码。
那么它将永远永远停留在数据库中吗?
Answers:
从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);
}
}
time()
它而不是会导致错误的代码(执行不是天生的。)。请求时间是由PHP自己设置的,它不是来自用户提供的任何数据。为什么会出现此漏洞?
通过重新措辞和重新设置格式,将讨论中的一些评论移到答案中。
基本上,归结为,除非您有一个极端的案例,否则它们实际上并不需要“收集垃圾”。如果您从不获取它们,那么它们是否存在都没关系。
请参阅,默认情况下,瞬态存储在选项表中。在基本安装中,选项表中可能包含100个条目。每个瞬变都会添加两个条目,但是即使您有数千个条目,它们也不会影响站点速度,因为它们不会自动加载。
在启动时,WordPress会将选项加载到内存中,但只会加载启用了自动加载标记的选项。瞬态不了解这一点,因此也不会加载到内存中。只有稍后实际使用的瞬变会产生成本。
从数据库的角度来看,选项表在选项ID和选项名称上都有索引。瞬态总是根据名称(键)加载的,因此对它们的查找始终是对单个唯一键值的简单选择。因此,查找为O(log(n)),并且超快。使用log(n)的Big-O,您必须先进入数百万行,然后才能注意到它。坦白说,查询的建立和删除以及实际数据传输的开销要长得多。通过比较,查询本身的运行时间基本上为零。因此,简单地拥有多余的未使用行不会影响任何事情,但会占用额外的磁盘空间。
在数据库中建立索引是一种深入了解的想法之一,它对实际上尚未了解幕后情况的人们没有意义。数据库是专为从头开始快速进行数据检索而设计的,可以毫无问题地处理这种事情。这是一本不错的书:http : //en.wikipedia.org/wiki/Index_(database)
现在,以最明显的方式进行清理(在它们上调用SQL DELETE)实际上并没有从数据库中删除它们。它只是将它们从索引中删除,并将该行标记为“已删除”。同样,这就是数据库的工作方式。要实际清除磁盘空间,您必须继续然后在之后执行OPTIMIZE TABLE,这不是一个快速的操作。这需要时间。可能花了更多时间。总的来说,这可能不足以节省CPU时间。
如果您有某种情况导致连续插入未使用的新瞬态,则需要查找潜在的问题。是什么插入这些瞬变?他们使用的是变更键还是变异键?如果是这样,那么导致此问题的插件或代码基本上应该固定为不这样做。这将更有帮助,因为未正确创建它们的代码也可能没有检索到它们,因此所要做的工作比必须要做的更多。
另一方面,可能会为每个帖子之类的内容创建瞬态。这确实可以完全接受。我自己在SFC中进行此操作,以存储来自Facebook的传入评论。每个帖子都有一个与之关联的潜在瞬变,这意味着每个帖子额外增加两行。如果您有1万条帖子,那么选项表中(最终)将有2万行。这并不坏,也不会很慢,因为同样,就数据库真正关心的而言,100行和20,000行之间的差异很小。全部索引。快得快。子毫秒以下。
当您开始进入数百万行时,我会担心。当选项表的大小增加到几百兆字节以上时,我将非常关注一下。但是总的来说,除了极端情况,这不是问题。对于比拥有数十万个帖子的大型新闻网站这样的小问题来说,这绝对不是问题。对于任何足以解决问题的站点,您都应该使用某种外部对象缓存,在这种情况下,瞬态会自动存储在此处而不是存储在数据库中。
奥托-我再也不同意你。问题在于,最终所有这些瞬变都会使表的大小变得可笑。无需花费数百万行就可以解决。我目前正在处理一个超过13万行的选项表,该表经常挂起。因为value字段是大文本类型,所以即使仅查找“自动加载”行也成为性能的噩梦。这些值字段与其余的行数据分开存储。即使从逻辑上讲它是同一张表的一部分,也必须进行联接才能提取所需的行。现在,由于需要的数据分布在磁盘上的所有位置,因此永久连接是永久的。分析(对MySQL使用jet profiler)已经证明了这一点。
将自动加载添加到群集密钥可能有助于解决此问题。例如,基于自动加载描述(ID ASC)的群集,将允许所有自动加载行首先在磁盘上聚集在一起。甚至我仍然认为您从数据库的角度来看正在承受巨大的压力。
我个人认为该系统的设计很糟糕。选项表似乎已经变成了很多事情的通用工具。如果value字段足够小,可以与该行数据的其余部分包含在同一页上,并且可以有效地对其进行索引,则可以。不幸的是事实并非如此。设计此方法的人需要回到DB101类。