Удаление всех записей произвольного типа записей—эффективный способ
Я ищу безопасный и быстрый способ удаления всех записей одного произвольного типа. Использование get_posts()
и wp_delete_post()
для каждой полученной записи не работает; это недостаточно быстро из-за огромного количества запросов к базе данных (возникает ошибка тайм-аута).
Предпочтительно, я ищу единственный запрос к базе данных, который удалит все записи определенного произвольного типа. Есть какие-нибудь идеи?

Вы можете удалить все записи через $wpdb
DELETE FROM wp_posts WHERE post_type='post_type';
DELETE FROM wp_postmeta WHERE post_id NOT IN (SELECT id FROM wp_posts);
DELETE FROM wp_term_relationships WHERE object_id NOT IN (SELECT id FROM wp_posts)
или используйте этот запрос, заменив {{your CPT}} на ваш тип записи (Custom Post Type)
DELETE a,b,c
FROM wp_posts a
LEFT JOIN wp_term_relationships b
ON (a.ID = b.object_id)
LEFT JOIN wp_postmeta c
ON (a.ID = c.post_id)
WHERE a.post_type = '{{your CPT}}';

это, вероятно, сработает, но не забывайте о количестве терминов в одной из таблиц терминов. В WordPress должна быть функция для обновления этого значения.

у пользователей также есть счетчики записей на экране пользователей, не уверен, сохраняются ли эти данные заранее или вычисляются при загрузке страницы.

@JoelM Столбец с количеством существует в таблице базы данных wp_term_taxonomy
. Похоже, что функция, которую вы ищете для обновления счетчика, это wp_update_term_count($terms, $taxonomy, false)
или wp_update_term_count_now($terms, $taxonomy)
, определенная в wp-includes/taxonomy.php
.

Теперь это можно сделать с помощью WordPress CLI, используя команду wp post delete. После установки CLI следующая команда в терминале (выполняемая в корневой директории вашего сайта) удалит все записи типа mycustomtype
:
wp post delete $(wp post list --post_type='mycustomtype' --format=ids)
Никаких сырых SQL-запросов (*фу*), никаких переживаний о таймаутах, и всё это быстро. Например, я только что удалил ~2500 записей менее чем за две минуты.
Чтобы пропустить Корзину и удалить записи полностью, используйте параметр --force

Это сработало для удаления ~12k записей. Обработал без проблем. Используйте флаг --force
, если хотите пропустить "корзину" и удалить навсегда.

Вы можете удалить все записи пользовательского типа поста различными способами, но здесь я покажу, как сделать это без использования SQL-запросов. В данном примере наш тип поста — product (товар)
$allposts = get_posts( array('post_type' => 'product', 'numberposts' => -1) );
foreach ($allposts as $eachpost) {
wp_delete_post( $eachpost->ID, true ); // Удаляем пост с указанным ID, включая вложения (true)
}

Прочтите исходный вопрос еще раз: "Использование get_posts()
и wp_delete_post()
для каждого возвращенного поста не работает; это недостаточно быстро из-за огромного количества запросов к базе данных (ошибка таймаута)."
Вы используете именно те две функции, которые он не хочет использовать.

Вы абсолютно правы. Но просто для перестраховки и чтобы также удалить термины, комментарии и метаданные с обновлением счетчиков терминов — это идеальный метод. Возможно, мы можем использовать для этого cron.

Если вы добавили префикс к типу записи CPT и таксономиям CPT, например, 'abc_мой_тип_записи' и 'abc_моя_таксономия', то удалить все из базы данных можно двумя простыми запросами:
DELETE a,b
FROM $wpdb->posts a
LEFT JOIN $wpdb->postmeta b ON a.ID = b.post_id
WHERE a.post_type LIKE 'abc_%';
DELETE a,b,c
FROM $wpdb->term_taxonomy a
LEFT JOIN $wpdb->term_relationships b ON a.term_taxonomy_id = b.term_taxonomy_id
LEFT JOIN $wpdb->terms c ON a.term_id = c.term_id
WHERE a.taxonomy LIKE 'abc_%'
