I’m trying to optimise the following query in wordpress, as it takes nearly a minute and a half to return a result. The table relationships are expressed in the following diagram:
SELECT SQL_CALC_FOUND_ROWS wp_posts . *
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)
WHERE 1 = 1
AND (
wp_term_relationships.term_taxonomy_id IN (25)
OR tt1.term_taxonomy_id IN (26)
OR tt2.term_taxonomy_id IN (16)
OR tt3.term_taxonomy_id IN (17)
OR tt4.term_taxonomy_id IN (18)
)
AND wp_posts.post_type IN ('product')
AND (wp_posts.post_status = 'publish')
GROUP BY wp_posts.ID
ORDER BY wp_posts.post_title ASC
LIMIT 0 , 15
I don’t understand the point of all the inner joins on the wp_term_relationships table when all it appears you’re doing is looking for a series of values. Wouldn’t the following perform the same and execute much faster?
Try this. I think this will be faster.
You do not need so many INNER JOINS.
If the idea behind the multiple joins was to retrieve the posts with a corresponding
term_taxonomy_id
of 25 and also 26 and also 17,… (meaning ALL of the terms as opposed to ANY of them), you can reuse KayakJim’s answer with only one JOIN and add anHAVING
clause, keeping only the rows that matched with all of the 5 terms.Here would be the modified query: