Есть ли способ исключить содержимое из переменной post, чтобы сэкономить на использовании оперативной памяти?


9

Итак, я столкнулся с проблемой использования оперативной памяти WP и ищу решение.

Единственное место, где у меня действительно возникает эта проблема на моем сайте, - это страница карты сайта, которую я пытаюсь заполнить, но решение этой проблемы может быть применено повсеместно и сэкономить на использовании оперативной памяти всего сайта.

По сути, эта страница «Карта сайта» у меня есть список всего postsи pagesна моем сайте. Единственные элементы переменной $ post, к которым мне нужен доступ на этой странице, - это заголовок и постоянная ссылка. К сожалению, используемый мной запрос возвращает все сообщения со всей информацией в каждой из переменных $ post.

Ниже приведен пример запроса, который я использую на этой странице карты сайта для одного custom-post-typeимени «продукты» с пользовательской таксономией «дополнения» и термина «все дополнения». Страница моей карты сайта содержит несколько таких запросов, но для пояснения я включаю только код для этого отдельного запроса.

 $varArray= array(
      'post_type' => 'products',
      'post_status' => 'publish',
      'supplements' => 'all-supplements',
      'posts_per_page' => -1,
      'orderby' => 'title',
      'order' => 'ASC'
 );
 $myProducts= new WP_Query($varArray);

Подавляющее большинство информации, сохраненной в переменной $ post (для моего сайта, и я предполагаю, что эта тенденция прослеживается для общего использования), находится в «контенте». Типичное использование ОЗУ для моей страницы карты сайта составляет ~ 140 МБ. (сообщает Debug Bar), в то время как использование для любой другой типичной страницы на моем сайте составляет 50-60 МБ. Большая разница. Вчера страница Карта сайта перестала работать (WSOD), и для ее исправления мне пришлось увеличить максимальный объем оперативной памяти, который может использовать WP. Поэтому я увеличиваю общие необходимые системные ресурсы из-за одной страницы.

Итак, я подхожу к своему вопросу.

Есть ли где-то в Wordpress путь / опция, которую я пропускаю, которая будет извлекать posts/ pagesкак обычный запрос, но НЕ получать содержимое для извлеченных постов?

Или, в качестве альтернативы, есть ли какой-нибудь более простой способ для меня получить только определенные элементы в данном запросе (Title / Permaklink / Slug / etc ...) вместо получения всей переменной $ post переменной shebang?

Мне кажется, что для многих приложений WP единственное место, где обычно требуется «контент» поста / страницы, - это страница pageили postстраница (очевидно, здесь есть исключения), и что доступ к полному контенту для постов / Страницы, полученные по запросу на других страницах, просто излишни. Если есть способ избежать загрузки всего контента для страниц списка сообщений, то можно сэкономить значительное количество оперативной памяти.

Любая помощь будет оценена.

Ответы:


8

Вы можете попробовать трюк с непосредственным запросом данных поста и настройкой filterполя объектов поста sampleперед его передачей, get_permalink()чтобы уменьшить использование памяти.

Посмотрите проблему использования памяти get_permalink для подробного объяснения.


Это решение отлично сработало. Ну, после небольшого спора это. :) Мне пришлось выяснить, как включить в запрос мою собственную таксономию / термин, но это очень помогло. Страница карты сайта теперь использует 70 МБ оперативной памяти (согласно отладочной панели). Спасибо за отличный указатель.
программист Дан

4

Вы можете попробовать добавить это в ваш массив:

'nopaging' => true,
'no_found_rows' => true,
'update_post_meta_cache' => false,
'update_post_term_cache' => false

Это кажется довольно очевидным, но по сути вы не запрашиваете все переменные записи и просто то, что вам нужно.


2

Программист Дэн, мужик!

Давайте начнем с пользовательских SELECTзапросов, используя $wpdbглобальные. В Кодексе есть отличная статья об отображении сообщений с помощью пользовательского запроса выбора . Если вы используете его, setup_postdata()вы можете просмотреть результаты, как если бы вы сидели в стандартном цикле Wordpress:

global $wpdb;

$sitemap_query = "
    SELECT $wpdb->posts.ID, $wpdb->posts.post_title, $wpdb->posts.guid
    FROM $wpdb->posts
    WHERE $wpdb->posts.post_status = 'publish' 
    AND $wpdb->posts.post_type IN ('post','supplement','another_post_type')
    ORDER BY $wpdb->posts.post_type, $wpdb->posts.post_title DESC
    ";

$sitemap_nodes = $wpdb->get_results($sitemap_query, OBJECT);

if( $sitemap_nodes ):
    global $post;
    foreach ( $sitemap_nodes as $post ):
        setup_postdata( $post );
        ?>

<!-- //Use standard Wordpress template tags for SELECT'd data within The Loop here -->
    <?php the_title() ?>
    <?php the_permalink() ?>

        <?php
    endforeach;
endif;

Этот запрос извлекает только идентификаторы сообщений, заголовки и идентификаторы GUID (используемые для определения постоянной ссылки), при этом абсолютно игнорируя все остальное. Кроме того , он упорядочивает результаты сначала post_typeто post_title, что Вы можете использовать несколько запросов , чтобы отделить типы почтовых (теоретически при небольшой потери производительности).

Очевидно, что вы можете отказаться от использования setup_postdata()и просто выполнить цикл $sitemap_nodesили выполнить запрос, чтобы получить результаты, которые вам нужны.

Если вы делаете вызов setup_postdata()и активируете режим отладки, вызовы, скорее всего, будут выплевывать уведомления слева и справа относительно (намеренно) недостающей информации. Возможно, вы захотите бросить @перед вызовом функции, чтобы подавить их после того, как подтвердите, что ваш пользовательский запрос работает правильно.

Но это должно помочь вам начать! Вы можете обратиться к следующей диаграмме базы данных (со страницы « Описание базы данных» в Кодексе), чтобы найти поля, которые нужно запросить:

Диаграмма базы данных Wordpress

РЕДАКТИРОВАТЬ:

Наиболее эффективное решение для памяти - это, вероятно, решение, сочетающее пользовательский SELECTзапрос с подсказкой @ Rarst :)


1

WP_Query имеет параметр «возврат полей», который выглядит следующим образом:

$args = array(
 'fields' => 'ids'
);
$query = new WP_Query( $args );

При использовании этого способа WP_Query возвращает только идентификаторы сообщений, а не весь объект сообщений. Тогда вы можете просто использовать get_permalink(), get_the_title()и другие функции сортировали WordPress , чтобы получить контент на основе почтового идентификатора.


1
Обратите внимание, что функции, которые принимают идентификатор сообщения, обычно сразу запускаются get_post()на нем для получения полных данных и, таким образом, полностью исключают цель получения идентификаторов в одиночку.
августа

1
Хорошо знать! Я был под впечатлением, что я был умным.
Далтон
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.