2015-12-07 55 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

相關問題