2015-12-07 18 views
0
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次选择。有没有更高效的方法?使一个子选择更有效?

+1

为什么不改变选择成WHERE categories.slug =图集“? –

+0

谢谢,另一个问题,如果我这样做,第一个条件返回超过1行,子选择查询将不会运行? – panthro

+0

我会完全删除这两个子选择。我不会选择使用categories.id,而是使用像前面示例中发布的示例中的categories.slug。 –

回答

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' 
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 
+0

经过测试 - 子查询更高效,无论如何 – panthro

相关问题