How to fix WordPress performance issues in 5 minutes

We heard this from many of our customers, so we have decided to write a quick cheat sheet about query performance in WordPress v5.4.1 and the WP_Query function.

If you have a lot of data or a complex application, WordPress may run some of queries quite slowly.  After we analyzed several customers' use cases, we found that there are potentially missing indexes, and by creating them queries can be executed 18 times faster!

Optimize your database, auto-magically.
Click to start, for free.

Background

In WordPress you can usually retrieve data without necessarily struggling with the internal classes, tables and global variables. WP_Query is one of the functions that will help to do that.

There are two key situations in which you may wish to use WP_Query.

The first allows you to fetch the posts you'd like to present on a WordPress page, for example, blog posts you'd like to present on the main blog or search results pages. In this case, the WP_Query function will be used as part of the The Loop:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php
// The Query
$the_query = new WP_Query( $args );
// The Loop
if ( $the_query->have_posts() ) {
    echo '<ul>';
    while ( $the_query->have_posts() ) {
        $the_query->the_post();
        echo '<li>' . get_the_title() . '</li>';
    }
    echo '</ul>';
} else {
    // no posts found
}
/* Restore original Post Data */
wp_reset_postdata();

The second main role of the WP_Query function is to allow developers to retrieve custom data and WordPress entities, without having to write custom raw SQL queries. It's used mainly when developing wordpress plugins or themes.

Complex queries using WP_Query

As soon as you start using complex queries, the bigger chances are that the auto-generated query will not be optimized. In this example we are using Nested Taxonomy to display posts that are in the quotes category OR both have the quote post format AND are in the wisdom category:

Optimize your database, auto-magically.
Click to start, for free.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
$args = array(
    'post_type' => 'post',
    'tax_query' => array(
        'relation' => 'OR',
        array(
            'taxonomy' => 'category',
            'field'    => 'slug',
            'terms'    => array( 'quotes' ),
        ),
        array(
                        'relation' => 'AND',
                        array(
                    'taxonomy' => 'post_format',
                    'field'    => 'slug',
                    'terms'    => array( 'post-format-quote' ),
                        ),
                        array(
                                'taxonomy' => 'category',
                                'field'    => 'slug',
                                'terms'    => array( 'wisdom' ),
                        ),
        ),
    ),
);
$query = new WP_Query( $args );

But I am not using SQL, how can I improve my queries performance?

Although you don't use SQL, WP_Query auto-generates SQL Select statements to retrieve the required data from the database.
WP_Query is an excellent function, but it cannot always generate the right query. Also, the query is often correct, but there are missing indexes that can speed up the query.

You can get these internal queries by enabling slow query log

Recommendations

  1. Enable the slow query log and analyze it for free.
  2. Find out which indexes are missing and which indexes are redundant, you can do it here. Adding relevant indexes based on your specific queries can have a huge impact.
  3. When using WP_Query and searching based on meta_value(s) and not only meta_key(s), you should consider creating this index:
    ALTER TABLE `wp_postmeta` ADD INDEX `wp_postmeta_idx_meta_key_meta_value_post_id` (`meta_key` (255),`meta_value` (255), `post_id`);
  4. If you have many records of other entities other than posts (for example, users), you should consider similar indexes on their meta values as well, in case you have queries which are querying that data.
  5. When creating new WordPress entities and writing WP_Queries to get their data, please make sure you properly index the new tables / columns based on your most important and frequent queries. You can also consider optimizing the queries automatically with EverSQL.

Example

Here is a great example of one of our customers who implemented these changes recently. You can see by yourself how fast it works.

Summary

Looking to speed up your WordPress application and optimizing its' database SQL queries? Start here for free.