首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >优化MySQL左连接查询

问优化MySQL左连接查询
EN

Stack Overflow用户
提问于 2012-06-20 08:36:13
回答 2查看 686关注 0票数 0

我的目标是选择primary_category_id (articles表)或任何二级类别(articles_secondary_categories连接表)是给定值的文章。在这个示例查询中,类别1。我尝试使用其他类型的连接,但这里需要注意的是,一篇文章可能没有任何辅助类别。

代码语言:javascript
复制
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秒。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-06-20 09:02:54

您可以反转对辅助类别的查询:

代码语言:javascript
复制
(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

票数 0
EN

Stack Overflow用户

发布于 2012-06-20 09:03:29

避免在where子句中使用OR。优化器通常不会将索引与OR谓词一起使用。

尝试将categories.category_id = 1移动到联接条件中:

代码语言:javascript
复制
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。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11111364

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档