简体   繁体   中英

Optimising mysql query - many inner joins

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?

SELECT SQL_CALC_FOUND_ROWS wp_posts . *
    FROM wp_posts
       INNER JOIN wp_term_relationships 
        ON (wp_posts.ID = wp_term_relationships.object_id)
    WHERE wp_term_relationships.term_taxonomy_id IN (25, 26, 16, 17, 18) 
        AND wp_posts.post_type = 'product' 
        AND wp_posts.post_status = 'publish'
    GROUP BY wp_posts.ID
    ORDER BY wp_posts.post_title ASC
    LIMIT 0 , 15

Try this. I think this will be faster.

SELECT SQL_CALC_FOUND_ROWS wp_posts . *
FROM wp_posts,
     wp_term_relationships 
WHERE wp_posts.ID = wp_term_relationships.object_id
AND wp_term_relationships.term_taxonomy_id IN (25,26,16,17,18)
AND wp_posts.post_type = 'product' 
AND wp_posts.post_status = 'publish'
GROUP BY wp_posts.ID
ORDER BY wp_posts.post_title ASC
LIMIT 0 , 15

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 an HAVING clause, keeping only the rows that matched with all of the 5 terms.

Here would be the modified query:

SELECT SQL_CALC_FOUND_ROWS wp_posts . *
    FROM wp_posts
       INNER JOIN wp_term_relationships 
        ON (wp_posts.ID = wp_term_relationships.object_id)
    WHERE wp_term_relationships.term_taxonomy_id IN (25, 26, 16, 17, 18) 
        AND wp_posts.post_type = 'product' 
        AND wp_posts.post_status = 'publish'
    GROUP BY wp_posts.ID
    HAVING count(*)=5
    ORDER BY wp_posts.post_title ASC
    LIMIT 0 , 15

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM