Intereting Posts

Переходный режим не работает для пользовательских циклов

Я работаю над темой WordPress. Поскольку мне нужно отображать отмеченные сообщения, связанные сообщения, некоторые виджеты с недавними сообщениями и т. Д., Мне нужно использовать несколько настраиваемых циклов. Из-за этого число запросов к базе данных также увеличилось.

В попытке оптимизировать тему для повышения производительности я столкнулся с http://codex.wordpress.org/Transients_API , который кажется хорошим способом кэширования циклов, которые мне не нужно обновлять до каждой перезагрузки страницы.

Пока все хорошо, я использовал переходный процесс для wp_nav_menu, и он работал так, как должен. Мне удалось немного уменьшить количество запросов db.

Проблема возникла, когда я попытался использовать переходный процесс для пользовательских циклов.

Переход сохраняется. Я могу получить переходную ценность. Единственная проблема заключается в том, что количество запросов к базе данных, по-видимому, значительно выше, чем при использовании WP_Query без переходного процесса.

Вот мой настраиваемый цикл:

if( false === ( $loop = get_transient('featured') ) ) { $loop = new WP_Query( array( 'posts_per_page' => 20 ) ); set_transient('featured', $loop, 60 * MINUTE_IN_SECONDS); } if( $loop->have_posts() ) : while( $loop->have_posts() ) : $loop->the_post(); the_title(); the_post_thumbnail('thumb'); endwhile; endif; wp_reset_postdata(); 

Код, используемый для отображения количества запросов к базе данных и времени выполнения, следующий:

 <?php echo get_num_queries(); ?> queries in <?php timer_stop(1); ?> seconds. 

Используя плагин отладки запроса, я вижу, что update_meta_cache () генерирует много запросов.

Я не могу объяснить, почему количество запросов к базе данных увеличивается, а не уменьшается, и почему это работает для меню, но не для пользовательских циклов. Может, я что-то пропустил. Любая помощь приветствуется.

Вчера я работал над сообщением (проверьте здесь ) и был поражен той же проблемой. Я также новичок в Transient API , никогда не работал с ним :-).

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

Чтобы объяснить, вот часть кода из ответа, о котором я говорил. Мне нужно создать список категорий с заголовками, относящимися к этим категориям. Чтобы выполнить это, я запускаю свой пользовательский запрос, а затем использую значение $q для создания списка

  $args = array( 'posts_per_page' => -1 ); $query = new WP_Query($args); $q = array(); while ( $query->have_posts() ) { $query->the_post(); $a = '<a href="'. get_permalink() .'">' . get_the_title() .'</a>'; $categories = get_the_category(); foreach ( $categories as $key=>$category ) { $b = '<a href="' . get_category_link( $category ) . '">' . $category->name . '</a>'; } $q[$b][] = $a; // Create an array with the category names and post titles } /* Restore original Post Data */ wp_reset_postdata(); 

Это дает мне 6 queries in 0.06348 seconds .

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

 <?php if( false === ( $query = get_transient('custom_query') ) ) { $args = array( 'posts_per_page' => -1 ); $query = new WP_Query($args); set_transient('custom_query', $query, 60 * MINUTE_IN_SECONDS); } $q = array(); while ( $query->have_posts() ) { $query->the_post(); $a = '<a href="'. get_permalink() .'">' . get_the_title() .'</a>'; $categories = get_the_category(); foreach ( $categories as $key=>$category ) { $b = '<a href="' . get_category_link( $category ) . '">' . $category->name . '</a>'; } $q[$b][] = $a; // Create an array with the category names and post titles } /* Restore original Post Data */ wp_reset_postdata(); ?> 

С приведенным выше кодом мои результаты выглядят примерно так: 31 queries in 0.19141 seconds . Это 25 запросов больше и занимает около 0.13 секунды. Причина этого заключается в том, что для каждого сообщения WordPress необходимо пересмотреть db, чтобы получить категории, к которым принадлежит сообщение, поскольку это не сохраняется в вас временным. 25 дополнительных запросов – количество сообщений в моем db. Итак, вы видите, вы действительно потратили много ресурсов, сохранив неправильную информацию. Мне не нужна информация из new WP_Query , но результат / значение от $ q

Таким образом, чтобы правильно использовать переходные процессы, вы должны сохранить правильные значения, которые вы после. Для этого мне нужно добавить свой полный запрос в переходный процесс, чтобы убедиться, что он запускается только один раз, и именно тогда создается переходный процесс. После этого пользовательский запрос больше не нужен и является избыточным, единственное, что нужно сохранить и что я сейчас – это значение $q . Таким образом, это изменение запроса для удаления пользовательского запроса после создания переходного процесса и сохранение только значения $q

Чтобы отметить, я изменил свои временные имена по пути только для целей тестирования, чтобы показать время и запросы. Также обратите внимание, что при создании вашего переходного процесса вам нужно использовать значение (в данном случае $q ), которое нужно сохранить

  if ( false === ( $q = get_transient( 'category_list' ) ) ) { $args = array( 'posts_per_page' => -1 ); $query = new WP_Query($args); $q = array(); while ( $query->have_posts() ) { $query->the_post(); $a = '<a href="'. get_permalink() .'">' . get_the_title() .'</a>'; $categories = get_the_category(); foreach ( $categories as $key=>$category ) { $b = '<a href="' . get_category_link( $category ) . '">' . $category->name . '</a>'; } $q[$b][] = $a; // Create an array with the category names and post titles } /* Restore original Post Data */ wp_reset_postdata(); set_transient( 'category_list', $q, 12 * HOUR_IN_SECONDS ); } 

Это даст мне 2 queries in 0.00195 seconds . Вы видите, как я теперь эффективно использовал переходные процессы. $q который представляет собой массив из многих значений`, теперь доступен для создания моего списка, и это только стоило мне 2 дБ хитов для достижения моей цели

Я надеюсь, что все это имеет смысл

У вашего кода 3 проблемы

  1. вы используете один запрос БД для сохранения другого запроса БД. Вы запрашиваете переходное значение вместо таблицы сообщений, которая может быть или не быть быстрее, но вы не сохраняете штраф за связь с БД.

  2. Вы не должны хранить объекты в переходных процессах или параметрах. Согласно значениям документации, предполагается, что они являются скалярами, которые могут быть причиной отказа get_transient в вашем коде. Одна из важных частей того, что делает wp_query, которое вы пропускаете тем, что может повлиять на производительность остальной части вашего кода, – это кэширование, сохраняя возвращаемые объекты сообщения в кеше (кеш в этом контексте является коротким для кеша сеанса)

  3. правильный способ кэширования – кэшировать сгенерированный HTML. Ваш код пытается сохранить один запрос, но вы сохраните еще 40, если кешировать HTML