我的目标是选择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 articles和7k articles_secondary_categories (非类别)的数据库中,运行此查询需要5秒。
发布于 2012-06-20 09:02:54
您可以反转对辅助类别的查询:
(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;它应该会给你一个不错的速度提升-只要确保你索引了categories.articles_id
发布于 2012-06-20 09:03:29
避免在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。
https://stackoverflow.com/questions/11111364
复制相似问题