使用wp_defer_term_counting有不利之处吗?


11

我有一个超过200万个帖子的WordPress数据库。每当我插入新帖子时,我都必须打电话wp_set_object_terms,这需要两秒钟的时间才能执行。我遇到了这篇文章,建议您致电wp_defer_term_counting以跳过术语计数。

如果使用这种方法,对WordPress的功能会产生严重影响吗?

这是帖子中的代码,以防万一链接失效:

function insert_many_posts(){
  wp_defer_term_counting(true);
  $tasks = get_default_tasks(); 
  for ($tasks as $task){
     $post = array(
       'post_title' => $task[content],
       'post_author' => $current_user->ID,
       'post_content' => '',
       'post_type' => 'bpc_default_task',
       'post_status' => 'publish'
     );
     $task_id = wp_insert_post( $post );

     if ( $task[category] )
        //Make sure we're passing an int as the term so it isn't mistaken for a slug
        wp_set_object_terms( $task_id, array( intval( $category ) ), 'bpc_category' );
  }
}

Answers:


8

这是关于此问题的一些想法,但是请注意,这决不是一个最终的答案,因为可能有些事情我被忽略了,但这应该使您对潜在的难题有所了解。


是的,从技术上讲可能会有后果。

wp_defer_term_counting(true)例如,当您正在批量插入帖子数据库并为每个对象分配术语作为过程的一部分时,调用真正变得有用。

在这种情况下,您将执行以下操作:

wp_defer_term_counting(true); //defer counting terms

//mass insertion or posts and assignment of terms here

wp_defer_term_counting(false); //count terms after completing business logic

现在以您的情况为例,如果您一次只插入一个帖子,那么递延术语计数仍将使您受益,但是,wp_defer_term_counting(false)如果您依赖于条件逻辑或其他逻辑/处理的术语计数。

为了进一步说明,假设您执行以下操作:

假设分类法中有3个术语product_cat,这些术语的ID分别为1(术语名称A),2(术语名称B)和3(术语名称C)。

以上每个术语的术语计数已经为5(仅用于示例)。

然后发生这种情况...

wp_defer_term_counting(true); //defer counting terms

$post_id = wp_insert_post($data);

wp_set_object_terms($post_id, array(1, 2, 3), 'product_cat');

然后,在以后的逻辑中,您决定提取该术语,因为您想评估与该术语关联的对象数量,并根据结果执行其他操作。

所以你这样做

$terms = get_the_terms($post_id, 'product_cat');

//let's just grab the first term object off the array of returned results
//for the sake of this example $terms[0] relates to term_id 1 (A)
echo $terms[0]->count; //result 5

//dump output of $terms above
array (
  0 => 
  WP_Term::__set_state(array(
     'term_id' => 1,
     'name' => 'A',
     'slug' => 'a',
     'term_group' => 0,
     'term_taxonomy_id' => 1,
     'taxonomy' => 'product_cat',
     'description' => '',
     'parent' => 0,
     'count' => 5, //notice term count still equal to 5 instead of 6
     'filter' => 'raw',
  )),
)

在我们的示例中,我们说术语名称A(term_id 1)已经有5个与之关联的对象,换句话说,术语计数为5。

因此,我们希望count上面返回的对象上的参数为6,但是由于您没有wp_defer_term_counting(false)在操作后调用,因此未针对适用的术语(术语A,B或C)更新术语计数。

因此,这是操作后不调用就调用的结果wp_defer_term_counting(true)wp_defer_term_counting(false)

现在的问题是,这对您有影响吗?如果您不需要调用get_the_terms或执行某些检索术语的操作,该count值将由您使用该值执行其他操作怎么办?好吧,在那种情况下,对您来说没有问题

但是...如果其他人迷上set_object_termswp_set_object_terms()函数的作用并且他们依靠正确的术语计数怎么办?现在,您可以了解可能会在何处产生后果。

还是在请求终止后执行另一个请求,以检索分类术语并count在其业务逻辑中使用该属性,该怎么办?那可能是个问题。

虽然听起来count可能会造成很大的伤害,但我们无法根据我们自己的哲学来假设使用这些数据的方式。

另外,如备用答案中所述,分类列表表上显示的计数也不会更新。

实际上,在您推迟术语计数且请求结束之后,更新术语计数的唯一方法是手动调用wp_update_term_count($terms, $taxonomy)或等待,直到有人通过分类法UI或以编程方式为给定分类法添加了术语。

值得深思。


1
我想你总结得很好。这取决于您是否要利用实际的术语数,就我所能挖掘的相关源代码而言
Pieter Goosen

3
是的,我认为这是一个有趣的问题,所以我不得不更深入地研究……似乎唯一的问题是,在同一请求期间甚至在请求结束后,是否需要准确的术语计数。仔细考虑一下,如果有人依靠术语计数来确定任何严肃的业务逻辑,那么您将无法保证所查看的内容实际上是正确的计数。wp_update_term_count()在使用计数值之前,您必须手动尝试更新计数(例如)。我不知道会是这种情况。
亚当

非常全面的答案。由于我实际上是在进行批量插入,因此,按照您的解释,我需要在之后遍历所有术语,然后wp_update_term_count($terms, $taxonomy)逐个调用, 对吗?
KalenGi

2
WordPress永远不会失败,给人以粗鲁的觉醒。我必须承认,有时候人们会学到更多诸如此类的回答问题,而不仅仅是在核心问题中充斥;-)
Pieter Goosen

1
如果你正在做大量的插入,我只想wp_defer_term_counting(true)做好群众INSERT然后wp_defer_term_counting(false)。您wp_update_term_count()直接调用的唯一原因是,如果将term_ids存储在瞬态中,然后完全延迟计数,但是例如在后台触发AJAX请求,抓住瞬态,然后手动调用wp_update_term_count()或使用cron-job或类似方法。如果您在同一请求中(在执行完全终止之前),则无论如何都wp_defer_term_counting(false)wp_update_term_count()在后台调用。
亚当

0

作为操作,这应该相对安全。这延迟了出现在“编辑分类法”页面上的术语计数。因此,似乎不会有任何严重的后果。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.