[英]Optimizing MySQL LEFT JOIN query
我的目標是選擇primary_category_id
( articles
表)或任何輔助類別( articles_secondary_categories
連接表)為給定值的文章。 在此示例查詢中,類別1。我嘗試使用其他類型的聯接,但這里的警告是,文章可能沒有任何二級類別。
SELECT DISTINCT articles.*
FROM articles
LEFT JOIN articles_secondary_categories AS categories
ON categories.article_id = articles.id
WHERE
(
primary_category_id = 1
OR
categories.category_id = 1
)
AND articles.state = "published"
AND edition_id = 1
ORDER BY publish_at DESC
LIMIT 10;
歡迎對此優化或替代方法有任何幫助。 在與4K一個DB articles
和7K articles_secondary_categories
(未分類)需要5秒鍾,運行此查詢。
您可以對次要類別進行反向查詢:
(SELECT articles.*
FROM articles
WHERE primary_category_id = 1)
UNION DISTINCT
(SELECT articles.*
FROM articles_secondary_categories AS categories
JOIN articles ON (categories.article_id = articles.id)
WHERE categories.category_id = 1
GROUP BY articles_id)
ORDER BY publish_at DESC
LIMIT 10;
它應該為您帶來不錯的速度提升-只需確保您為category.articles_id編制索引
避免在where子句中使用OR
。 優化器通常不使用帶有OR
謂詞的索引。
嘗試將categories.category_id = 1
移到聯接條件中:
SELECT articles.*
FROM articles
LEFT JOIN articles_secondary_categories AS categories
ON categories.article_id = articles.id and categories.category_id = 1
WHERE 1 in (ifnull(categories.category_id, primary_category_id), primary_category_id)
AND articles.state = "published"
AND edition_id = 1
ORDER BY publish_at DESC
LIMIT 10;
該查詢的關鍵字為1 in (ifnull(categories.category_id, primary_category_id), primary_category_id)
,它表示“如果我們加入了類別的連接,請在列表中使用它,否則使用primary_category_id,並且在所有情況下都使用primary_category_id 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.