WordPress wp_query taking a long time

I have a wordpress site where I have a wp_query with the following argument:

array(
    'post_status' => 'publish',
    'post_type' => 'post',
    'offset' => 0,
    'posts_per_page' => 21,
    'tax_query' =>
        array(
            0 => array(
                    'taxonomy' => 'category',
                    'field' => 'id',
                    'terms' => 5
            ),
            1 => array(
                    'taxonomy'] =>'category',
                    'field'] =>'id',
                    'terms'] =>17
            ),
            2 => array(
                    'taxonomy'] =>'category'
                    'field'] =>'id'
                    'terms'] =>20
            ),
            3 => array(
                    'taxonomy' => 'category'
                    'field' => 'id'
                    'terms' => 33
            ),
            4 => array(
                    'taxonomy' => 'category',
                    'field' => 'id',
                    'terms' => 55
            ),
            5 => array(
                    'taxonomy' => 'category',
                    'field' => 'id',
                    'terms' => 83
            ),
            'relation' => 'OR'
        )
    )

The problem with this is that everytime there is a change in a post, this query takes almost a minute to complete. Has anyone had this issue before? This generates a sql like this by the way:

Read More
SELECT SQL_CALC_FOUND_ROWS wp_posts.ID 
FROM wp_posts 
INNER JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id)
INNER JOIN wp_term_relationships AS tt1 ON (wp_posts.ID = tt1.object_id) 
INNER JOIN wp_term_relationships AS tt2 ON (wp_posts.ID = tt2.object_id) 
INNER JOIN wp_term_relationships AS tt3 ON (wp_posts.ID = tt3.object_id) 
INNER JOIN wp_term_relationships AS tt4 ON (wp_posts.ID = tt4.object_id) 
INNER JOIN wp_term_relationships AS tt5 ON (wp_posts.ID = tt5.object_id) 

WHERE 1=1 
AND ( wp_term_relationships.term_taxonomy_id IN (5) 
OR tt1.term_taxonomy_id IN (17) 
OR tt2.term_taxonomy_id IN (20) 
OR tt3.term_taxonomy_id IN (33) 
OR tt4.term_taxonomy_id IN (55) 
OR tt5.term_taxonomy_id IN (83) ) 
AND wp_posts.post_type = 'post' 
AND ((wp_posts.post_status = 'publish')) 

GROUP BY wp_posts.ID 
ORDER BY wp_posts.post_date DESC 
LIMIT 0, 21

Thanks for any help.

Related posts

Leave a Reply

1 comment

  1. One thing you can do is tweak the tax_query parameter; you’re joining the same table six times, and each one has an IN statement – that’s producing some very inefficient SQL, as you’ve noticed.

    The manual page for WP_Query has a few examples for tax_query, and it looks like you can combine all those different IDs into a single entity, which will reduce the SQL complexity considerably.

    array(
        'post_status' => 'publish',
        'post_type' => 'post',
        'offset' => 0,
        'posts_per_page' => 21,
        'tax_query' =>
            array(
                0 => array(
                        'taxonomy' => 'category',
                        'field' => 'id',
                        'terms' => array (5, 17, 20, 33, 55, 83), 
                )            )
        )
    

    That should fetch terms with any of those IDs, and should do it more efficiently.