1

I have the following code in the footer (I have removed unnecessary html) which I am trying to optimize. My server is suffocating during the day :) If posts_per_page is set to 1, there are 48 queries per post. If I set it to 18 like I want to, there are 86 queries per post, which for me it seems huge, especially since I have 1500 posts. Is there a way to optimize this? Why can't WP_Query get the job done in a single query?

 $footer_query = new WP_Query(array(

     'posts_per_page' => 18,
     'orderby' => 'rand',
     'post_type' => 'post',
     'post_status' => 'publish',
     'no_found_rows' => true, // counts posts, remove if pagination require
     'update_post_term_cache' => false, // grabs terms, remove if terms required (category, tag...)
     // look for post which has featured img
     'meta_query' => array(
       array(
          'key' => '_thumbnail_id',
            )
      )
      ));


      // LOOP
      if ($footer_query->have_posts()) :
       while ($footer_query->have_posts()) : $footer_query->the_post(); 
      ?>

         <a href="<?php the_permalink() ?>">
           <?php echo get_the_post_thumbnail( get_the_ID(), 'small_thumbnail', array('class' => 'img-responsive') ); ?>
         </a>

        <a href="<?php the_permalink() ?>">
            <?php the_title(); ?>
            <?php echo get_field('subtitle', get_the_ID()); ?>
        </a>

   <?php
   endif; 
   endwhile; 

 wp_reset_query(); 

1 Answer 1

2

The big issue you have here is calling your post thumbnails. That adds about two queries per post, which is quite heavy. When we look at the source code of get_the_post_thumbnail(), we will see that the thumbnails is only cached on the main query, and not custom queries. So we would need to do that manually.

You can add

update_post_thumbnail_cache( $footer_query );

just before your loop. This should take care of the large amount of db calls

Just a few notes on your code

  • You should be using wp_reset_postdata() after the loop, not wp_reset_query(), latter is used in conjuction with query_posts which you should never use. wp_reset_postdata() should also be called between endwhile and endif

  • Random ordering is always much slower than any other ordering as it still goes through the complete db in order to pick random posts, so you might want to look into this

  • It is unnecessary defining arguments with their default values. post_type by default is set to post and post_status to publish

  • Properly indent your code to make it more readable, maintainable and debuggable

  • As from PHP 5.4, you can use short array syntax which requires less writing ;-)

You can probably rewrite your code as follow

$args = [
    'posts_per_page' => 18,
    'orderby'        => 'rand',
    'no_found_rows'  => true, // counts posts, remove if pagination require
    // look for post which has featured img
    'meta_query'     => [
        [
            'key'    => '_thumbnail_id',
        ]
    ]
];
$footer_query = new WP_Query( $args );

// Update the thumbnail cache
update_post_thumbnail_cache( $footer_query );

// LOOP
if ($footer_query->have_posts()) :
    while ($footer_query->have_posts()) : 
        $footer_query->the_post(); 
        ?>

        <a href="<?php the_permalink() ?>">
            <?php echo get_the_post_thumbnail( get_the_ID(), 'small_thumbnail', array('class' => 'img-responsive') ); ?>
        </a>

        <a href="<?php the_permalink() ?>">
            <?php the_title(); ?>
        </a>

        <?php

    endwhile; 
    wp_reset_postdata();
endif;
2
  • Thank you so much! currently it is on 58 queries :) I didn't know about update_post_thumbnail_cache, it isn't explained in the Codex either Commented Feb 17, 2016 at 20:54
  • Glad it helped. The codex are not always up to date, neither is it always correct ;-). Enjoy Commented Feb 18, 2016 at 4:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.