WP_Query, после обновления wp - Неустранимая ошибка: допустимый размер памяти 536870912 байт исчерпан (попытка выделить * байт) в /class-wpdb.php в строке 2187

После обновления 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 в фоновом режиме делают некоторые тяжелые дополнительные вещи.

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
1
0
55
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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 решило проблему, теперь для запроса требуется на 1,2 ГБ меньше оперативной памяти, какое чудо :D, боролся с этим 3 дня, спасибо! . Я не был уверен, было ли причиной обновление WP, но теперь, если посмотреть глубже, в 6.1 добавлено следующее: «Важным повышением производительности является добавление кэширования в WP_Query в базе данных». , с одной стороны это хорошо с другой катастрофа. Потому что даже select приводит к тому, что WP обновляет все поля поста ACF в кеш, что ТЯЖЕЛО. github.com/algolia/algoliasearch-wordpress/blob/master/inclu‌​des/…

Jiro Matchonson 26.01.2023 15:10

Но мне интересно, у меня могут быть более тяжелые запросы в приложении, его проекту уже несколько лет, есть ли способ установить «update_post_meta_cache» => false по умолчанию для всего проекта? Или я должен просмотреть весь код и просто решить причину за причиной вручную?

Jiro Matchonson 26.01.2023 15:13

Круто, хотя я не очень понимаю, что эта функция делает на самом деле. Он везде заменяет update_post_metadata_cache пустой функцией? Значит, wp 6 будет вести себя так же, как и wp 5? Что означают эти два числа? "10, 2);" . Может ли это что-нибудь сломать, не должно? Он должен вести себя как раньше? Или, может быть, я мог бы добавить что-то вроде этого, только когда лимит выше 200?, или количество сообщений больше, чем какое-то количество?

Jiro Matchonson 27.01.2023 13:55

Пожалуйста, смотрите мое редактирование. И объяснение того, как использовать хуки фильтров и действий, выходит за рамки ответа Stack Overflow, хотя это жизненно важный навык для разработчиков WordPress.

O. Jones 27.01.2023 15:02

Другие вопросы по теме