После обновления wordpress с 5 до wp 6.1.1 wp_query (или query_posts) потребляет абсурдное количество памяти при очень простом запросе, который перечисляет 1000 пользовательских сообщений. У меня в базе 16000 постов такого типа. и множество настраиваемых полей ACF, но в предыдущей версии wordpress проблем не было.
Я пробовал все это,
wp_suspend_cache_addition (истина); - нет эффекта
'fields' => 'id', - без эффекта
'cache_results' => false, - без эффекта
Всегда заканчивается фатальной ошибкой: допустимый размер памяти 536870912 байт исчерпан (пытался выделить * байты) в /class-wpdb.php в строке 2187
Я оставил только запрос, который
$quotesToGetProcessedArgs = [
'post_type' => 'QuoteRequest',
'post_status' => 'publish',
'offset' => '0',
'posts_per_page' => 1000,
'fields' => 'ids',
'cache_results' => false,
];
$quotesToGetProcessed = new WP_Query($quotesToGetProcessedArgs);
while ($quotesToGetProcessed->have_posts()) : $quotesToGetProcessed->the_post();
//do nothing
endwhile;
wp_reset_postdata();
Как видите, даже если я ничего не делаю и запрашиваю только идентификаторы, запрос съедает абсурдное количество памяти (около 1,5 ГБ!!!!), я смог временно решить эту проблему, добавив ini_set('memory_limit', '1500M '); , но это не реальное решение, при разработке, где у меня более старый WordPress, все работает, поэтому я подозреваю, что некоторые изменения wp6 в фоновом режиме делают некоторые тяжелые дополнительные вещи.
6.1.1 помещает в свой кеш больше информации о каждом прочитанном сообщении, чем 5.x, для повышения производительности. Похоже, что ваш запрос 'posts_per_page' => 1000
помещает мета- и терминологические данные на 1000 сообщений в кеш, тем самым выгружая оперативную память вашего веб-хоста.
Имейте в виду, что цель использования базы данных состоит в том, чтобы позволить вашему приложению обрабатывать данные, которые намного больше, чем ваша оперативная память. Но вы должны обрабатывать это партия за партией, а партии должны помещаться в ОЗУ.
Как это исправить? Самый простой выбор — использовать меньшее количество постов.
Другой может заключаться в том, чтобы добавить эти строки в ваш запрос. Ваш запрос подавляет обновление кеша сообщений. Вы также можете запретить обновление метаданных и кешей терминов, используя эти строки аргумента запроса для управления кэшированием.
'cache_results' => false, /* you have this already */
'update_post_meta_cache' => false,
'update_post_term_cache' => false,
РЕДАКТИРОВАТЬ Если это ваш код, лучше всего уменьшить размер пакета posts_per_page
до чего-то < 100. Разработчики ядра WordPress добавляют больше кэширования в будущие версии, что сделает большие размеры пакетов еще менее жизнеспособными в качестве метода программирования.
Или вы можете использовать фильтр для подавления обновления метакеша. Но делайте это осторожно; вы можете замедлить работу, если будете делать это везде.
/**
* Short-circuits updating the metadata cache.
*
* @since 5.0.0
*
* @param mixed $check Whether to allow updating the meta cache of the given type.
* @param int[] $object_ids Array of object IDs to update the meta cache for.
*/
function jiro_skip_update_metadata_cache( $check, $posts ) {
return array();
}
add_filter ( 'update_post_metadata_cache', 'jiro_skip_update_metadata_cache' 10, 2 );
(Я использовал ваше имя в названии функции, потому что эти функции загрязняют глобальное пространство имен в WordPress.)
Этот фильтр вызывается из update_meta_cache() в этих строках кода. Он использует довольно распространенный паттерн WordPress, в котором возврат из фильтра чего-либо, отличного от нуля, заставляет функцию пропускать (сокращать) часть работы, которая может быть дорогостоящей.
Надежное использование такого рода фильтров требует просмотра исходного кода или даже пошагового выполнения кода с помощью отладчика, чтобы убедиться, что вы получите желаемый результат.
И вы можете использовать https://wpdirectory.net , чтобы увидеть, как он используется другими плагинами или темами в репозитории. Вот результат.
Но мне интересно, у меня могут быть более тяжелые запросы в приложении, его проекту уже несколько лет, есть ли способ установить «update_post_meta_cache» => false по умолчанию для всего проекта? Или я должен просмотреть весь код и просто решить причину за причиной вручную?
Круто, хотя я не очень понимаю, что эта функция делает на самом деле. Он везде заменяет update_post_metadata_cache пустой функцией? Значит, wp 6 будет вести себя так же, как и wp 5? Что означают эти два числа? "10, 2);" . Может ли это что-нибудь сломать, не должно? Он должен вести себя как раньше? Или, может быть, я мог бы добавить что-то вроде этого, только когда лимит выше 200?, или количество сообщений больше, чем какое-то количество?
Пожалуйста, смотрите мое редактирование. И объяснение того, как использовать хуки фильтров и действий, выходит за рамки ответа Stack Overflow, хотя это жизненно важный навык для разработчиков WordPress.
Добавление 'update_post_meta_cache' => false решило проблему, теперь для запроса требуется на 1,2 ГБ меньше оперативной памяти, какое чудо :D, боролся с этим 3 дня, спасибо! . Я не был уверен, было ли причиной обновление WP, но теперь, если посмотреть глубже, в 6.1 добавлено следующее: «Важным повышением производительности является добавление кэширования в WP_Query в базе данных». , с одной стороны это хорошо с другой катастрофа. Потому что даже select приводит к тому, что WP обновляет все поля поста ACF в кеш, что ТЯЖЕЛО. github.com/algolia/algoliasearch-wordpress/blob/master/includes/…