简体   繁体   中英

Make a sub select more efficient?

SELECT *
FROM articles 
LEFT JOIN categories ON categories.id = articles.category_id
WHERE categories.id = (
    SELECT id
    FROM categories 
    WHERE slug = 'portfolio'
)
OR categories.parent_id = (
    SELECT id
    FROM categories 
    WHERE slug = 'portfolio'
)

How can I make this sub select more efficient? Im basically getting the id of portfolio and matching that but it may perform 2 sub selects. Is there a more efficient way?

There is no need to have subselects at all in this query! The 1st subselect can be turned straight into a plain where criterion: categories.slug = 'portfolio' . To replace the 2nd subselect you need to join the categories table once more to get the parent category and filter in the where clause.

You can also consider rewriting this as a union to optimise index usage.

SELECT articles.*, categories.* FROM articles LEFT JOIN categories ON categories.id = articles.category_id
WHERE categories.slug = 'portfolio'
UNION DISTINCT
SELECT articles.*, c1.* FROM articles LEFT JOIN categories c1 ON c1.id = articles.category_id
LEFT JOIN categories c2 ON c2.id=c1.parent_id
WHERE c2.slug = 'portfolio'

You can solve this by joining the category table again as the parent:

SELECT * FROM articles 
LEFT JOIN categories 
    ON categories.id = articles.category_id
LEFT JOIN categories parent
    ON parent.id = categories.parent_id
WHERE categories.slug = 'portfolio'
or parent.slug = 'portfolio'

The sub selects are removed entirely.

Another method for removing the duplicate sub selection would be using a table expression:

WITH cat AS
(
    SELECT id
    FROM categories 
    WHERE slug = 'portfolio'
)
SELECT *
FROM articles 
JOIN categories 
    ON categories.id = articles.category_id
JOIN cat
    ON cat.id = categories.id
    OR cat.id = categories.parent_id

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