0

I am on a mission to optimise a large site. The site has quite a lot of posts

On the archive page, only the excerpt, thumbnail and post title of a custom post type is displayed. The image and title both link to its respective page.

Each archive page has around 15 posts on it but returning 92 queries. Without any posts loaded, so just navigation and footer widgets there are around 40 queries.

I have read there is a way to stop WP from search the database for certain things, so literally just what I need.

Here is my current custom post type query:

<?php
    $args = array( 'post_type' => 'venues', 'orderby' => 'menu_order', 'order' => 'ASC', 'posts_per_page' => 15);
    $loop = new WP_Query( $args );
    if( $loop->have_posts() ):
    while( $loop->have_posts() ): $loop->the_post(); global $post;
?>

<li class="venue-item"  itemscope="" itemtype="http://schema.org/Article">
    <div class="featured-image">
    <a href="<?php the_permalink(); ?>" title="<?php the_title(); ?>" rel="bookmark"><?php the_post_thumbnail();?></a>
    </div>

<div class="one-third">
    <div class="venue-description">
        <a href="<?php echo get_permalink();?>"><h3 itemprop="headline"><?php echo get_the_title(); ?> </h3></a>
        <p itemprop="description"><?php the_excerpt() ?></p>
    </div>
</div>
</li>
<?php endwhile; endif; ?>

Is there any way to optimise this query so only get what is needed from the database? It's not about making the page load faster as it's already super fast and sitting behind Varnish, it's about making the site scale as they're expecting a large traffic spike (from 1000 visits a day to around 5000 apparently) in the next week or two so anything I can do to help my server out is good for me!

There aren't many plugins active on the site; ithemes security, yoast, varnish purge and ACF so it's pretty good anyway just trying to see if I can do any more! Thank you in advance.

1 Answer 1

3

Your big issue here is, you are running a custom query in place of the main query which you should never ever do. I have done a quite extensive post on this very issue, you be sure to properly read that post first. By going back to the default loop and using pre_get_posts to alter the main query accordingly, you will save a huge amount of db calls. Remember, even if you delete the main loop and replace it with a custom one, the main query still runs normally. By replacing the main query with a custom one only leads to more extra work and db calls being done. It is like doing the same exact job twice and only getting paid once.

You also need to remember that, post thumbnails does not get cached for custom queries, so this alone leads to 2 extra db calls per post. That is why you see the huge amount of queries from your custom query. You can have a look at this post on how to optimize this

EDIT

You should replace your code in your archive page which is in your question with the following code. You should not have any custom query in place of the main query.

<?php
    if( have_posts() ):
        while( have_posts() ): 
            the_post(); 
            ?>

            <li class="venue-item"  itemscope="" itemtype="http://schema.org/Article">
                <div class="featured-image">
                    <a href="<?php the_permalink(); ?>" title="<?php the_title(); ?>" rel="bookmark">
                        <?php the_post_thumbnail();?>
                    </a>
                </div>

                <div class="one-third">
                    <div class="venue-description">
                        <a href="<?php echo get_permalink();?>"><h3 itemprop="headline">
                            <?php echo get_the_title(); ?> </h3>
                        </a>
                        <p itemprop="description">
                            <?php the_excerpt() ?>
                        </p>
                    </div>
                </div>
            </li>
            <?php 
        endwhile; 
    endif; 
?>

This should see a drop in queries. All you need to do now is to alter the main query to suit your needs

add_action( 'pre_get_posts', function ( $q )
{
    if (    !is_admin()
         && $q->is_main_query()
         && $q->is_post_type_archive( 'venues' )
    ) {
        $q->set( 'order',          'ASC'        );
        $q->set( 'orderby',        'menu_order' );
        $q->set( 'posts_per_page', 15           );
    }
});
5
  • Thank you for your answer. I have included pre_get_post in functions but it seems to only get rid of 3 queries. I am having real trouble sorting the actual query on the archive page though and I haven't quite sussed out the caching bit yet. Are you able to give me an example in my case?
    – WPDEVE
    Apr 2, 2016 at 8:17
  • Actually, It only went down to 91 queries so saving of 1:(
    – WPDEVE
    Apr 2, 2016 at 8:29
  • Please see my edit Apr 2, 2016 at 9:56
  • You are an absolute star. This archive page is now down to 54 queries!!! Would I benefit from including your image caching code from the link you provided? AND I have tried to use the above on my homepage, which has 9 of those venues, and the last three blog posts. I tried to basically copy what was on my venue archive to the homepage but it didn't like this much at all!
    – WPDEVE
    Apr 2, 2016 at 15:46
  • My pleasure, glad it worked. Thumbnails are auto cached for the main query, so that is not necessary. You should download the Query Monitor plugin. This will point to each and every query run and time taken. This is a great tool to identify bloated queries Apr 3, 2016 at 6:19

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.