使子选择更有效?

时间:2015-12-07 21:47:00

标签: mysql

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'
)

如何让这个子选择更有效?我基本上得到了投资组合的ID和匹配,但它可以执行2个子选择。有更有效的方法吗?

2 个答案:

答案 0 :(得分:1)

此查询中根本不需要子选择!第一个子选择可以直接转换为标准:categories.slug = 'portfolio'。要替换第二个子选择,您需要再次加入类别表以获取父类别并过滤where子句。

您还可以考虑将其重写为联合以优化索引使用。

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'

答案 1 :(得分:0)

您可以通过再次将类别表作为父级来解决此问题:

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'

完全删除子选择。

删除重复子选择的另一种方法是使用表表达式:

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