wp_defer_term_counting()WP 2.5.0

Позволяет отложить пересчет количества постов для термина (элемента таксономии).

Функция предназначена для ускорения операций импорта или добавлении/удалении большого количества постов.

По умолчанию при добавлении или удалении поста сразу вызывается wp_update_term_count(), и WordPress пересчитывает количество записей в связанном термине. Если постов много, это создаёт сотни ненужных пересчетов и сильно замедляет работу.

Эта функция позволяет временно отключить пересчет: WordPress просто запоминает ID терминов, где произошли изменения. Когда все операции (например, импорт 500 постов) завершены, можно вызвать пересчет один раз, и он обновит количество записей сразу для всех затронутых терминов.

То есть вместо десятков или сотен пересчетов вы получаете один финальный пересчет — быстрее и эффективнее.

Пример:

wp_defer_term_counting( true ); // отключаем пересчет

// делем что нужно

wp_defer_term_counting( false ); // пересчитывем для всех

Смотрите также:

Хуков нет.

Возвращает

true|false. Включен или отключен подсчет постов в элементе таксономии.

Использование

wp_defer_term_counting( $defer );
$defer(true|false)
  • true - отключит фактический пересчет постов для функции wp_update_term_count() и включит сохранение ID терминов для которых нужно сделать пересчет
  • false - обработает все сохраненные ID терминов - сделает пересчет постов для каждого сохраненного термина.
  • null - просто вернет текущее значение Включен или отключен подсчет постов.

По умолчанию: null

Примеры

0

#1 Ускорение импорта большого количества постов

Допустим нам нужно добавить в БД 1000 постов для каждого из которых будет назначена своя рубрика и теги. У нас на сайте 20 рубрик и 50 тегов, т.е. в одни и те же рубрики и теги попадут разные посты. Поэтому в этом случае можно оптимизировать код импорта, отложив пересчет кол-ва постов для каждой рубрики и тега.

$posts_data = [ ... ];

// отключает пересчет постов в рубриках и собирает ID
wp_defer_term_counting( true );

// импорт
foreach( $posts_data as $post_data ){
	wp_insert_post( $post_data );
}

// пересчитываем посты в рубриках для всех собранных ID
wp_defer_term_counting( false );
0

#2 Отложенные пересчет постов в тегах при удалении тегов

Допустим у нас есть много похожих по названию тегов и мы хотим оптимизировать теги - собрать все похожие теги в группы, выделить из них основной тег и переместить все посты в основной тег, а остальные теги удалить.

Удалить теги и переместить их посты в основной тег можно функцией wp_delete_term() с дополнительными параметрами:

$delete_tag = 25;
$main_tag = 15;

wp_delete_term( $delete_tag, 'post_tag', [ 'default'=>$main_tag, 'force_default'=>1 ] );

Для каждого перемещенного поста будет вызвана функция wp_update_term_count(). Так например, если в группе у нас оказалось 4 тега (один основной) и в трех не основных находится, например, 20 постов, то при удалении этих 3 тегов 20 постов попадут в основной тег и функция пересчета будет вызвана 20 раз.

Чтобы этого избежать и вызвать функцию пересчета один раз вместо 20 можно отложить пересчет:

$delete_tags_groups = [ ... ];

// отключает пересчет постов в тегах и собирает ID тегов
wp_defer_term_counting( true );

// удаление тегов
foreach( $delete_tags_groups as $tags ){
	$main_tag = array_shift( $tags );

	foreach( $tags as $delete_tag ){
		wp_delete_term( $delete_tag, 'post_tag', [ 'default'=>$main_tag, 'force_default'=>1 ] );
	}
}

// пересчитываем посты в тегах для всех собранных ID тегов
wp_defer_term_counting( false );
0

#3 Ускорение удаления постов

Например нам нужно удалить 1 000 000 постов, чтобы ускорить этот процесс можно использовать следующий код:

wp_suspend_cache_addition( true );
wp_defer_term_counting( true );

$to_delete = [ 15,12,14, ... ];

// отключает пересчет постов в рубриках и собирает ID
wp_defer_term_counting( true );

// импорт
foreach( $to_delete as $post_id ){
	wp_delete_post( $post_id, true );
}

// пересчитываем посты в рубриках для всех собранных ID
wp_defer_term_counting( false );

Список изменений

С версии 2.5.0 Введена.

Код wp_defer_term_counting() WP 6.9

function wp_defer_term_counting( $defer = null ) {
	static $_defer = false;

	if ( is_bool( $defer ) ) {
		$_defer = $defer;
		// Flush any deferred counts.
		if ( ! $defer ) {
			wp_update_term_count( null, null, true );
		}
	}

	return $_defer;
}
2 комментария