Есть ли обратная сторона использования wp_defer_term_counting?

11

У меня есть база данных WordPress с более чем 2 миллионами сообщений. Всякий раз, когда я вставляю новое сообщение, мне нужно позвонить, выполнение 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' );
  }
}
KalenGi
источник

Ответы:

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, идентификаторы для этих терминов: 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_termsдействию в wp_set_object_terms()функции, и он полагается на правильность подсчета терминов? Теперь вы видите, где могут возникнуть последствия.

Или что, если после завершения запроса выполняется другой запрос, который извлекает термин таксономии и использует countсвойство в своей бизнес-логике? Это может быть проблемой.

Хотя это может показаться неправдоподобным, что countзначения могут принести большой вред, мы не можем предполагать, как такие данные будут использоваться на основе нашей собственной философии.

Также, как упомянуто в альтернативном ответе, количество, показанное в таблице списка таксономий, также не будет обновлено.

Фактически, единственный способ обновить подсчет сроков после того, как вы отложили подсчет сроков и ваш запрос закончился, - это вручную вызвать wp_update_term_count($terms, $taxonomy)или подождать, пока кто-нибудь не добавит термин для данной таксономии либо через пользовательский интерфейс таксономии, либо программно.

Пища для размышлений.

Адам
источник
1
Я думаю, что вы суммируете это блестяще. Все зависит от того, собираетесь ли вы использовать фактическое количество терминов, насколько я могу, копаясь в связанном исходном коде
Питер Гусен
3
Да, я подумал, что это интересный вопрос, поэтому мне пришлось копать глубже ... Кажется, единственная проблема заключается в том, требуется ли точное подсчет сроков во время того же запроса и даже после того, как запрос закончился. Если подумать, если кто-то когда-либо полагается на подсчет терминов для какой-либо серьезной бизнес-логики, тогда вы не можете быть уверены, что то, на что вы смотрите, на самом деле является правильным подсчетом. Вы должны вручную попытаться обновить счетчик (например wp_update_term_count()), прежде чем использовать его значение. Я понятия не имел, что будет так.
Адам
Очень полный ответ. Так как я на самом деле делаю массовую вставку, из того, что вы объяснили, мне нужно последовательно просмотреть термины и вызвать wp_update_term_count($terms, $taxonomy)каждое из них, верно?
KalenGi
2
WordPress никогда не перестает давать грубое пробуждение. Я должен признать, что иногда можно узнать больше, отвечая на подобные вопросы, чем просто разбираться в ядре в целом ;-)
Питер Гусен
1
Если вы делаете массовую вставку, я бы просто wp_defer_term_counting(true), DO MASS ВСТАВИТЬ тогда 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

Это должно быть относительно безопасно как операция. Это откладывает подсчет терминов, отображаемых на странице «Изменить таксономию». Так что не похоже, что будут какие-то серьезные последствия.

phatskat
источник