gpt4 book ai didi

mysql - 使用许多 LEFT JOIN 提高 SQL 查询的性能

转载 作者:可可西里 更新时间:2023-11-01 07:57:08 24 4
gpt4 key购买 nike

我有一个数据库结构,提供具有以下关联的新闻文章:

  • HABTM news_categories
  • HABTM 标签
  • HABTM 上传

我已经编写了一个 SQL 查询来将所有这些整合在一起:

 SELECT `news_articles`.*, 
GROUP_CONCAT(DISTINCT tags.title) AS `tags`,
GROUP_CONCAT(DISTINCT tags.id) AS `tag_ids`,
GROUP_CONCAT(DISTINCT news_categories.title) AS `news_categories`,
GROUP_CONCAT(DISTINCT news_categories.id) AS `news_category_ids`,
GROUP_CONCAT(DISTINCT news_categories.slug) AS `news_category_slugs`,
`news_articles_uploads`.`caption` AS `upload_caption`,
`uploads`.`title` AS `upload_title`,
`uploads`.`basename` AS `upload_basename`,
`uploads`.`extension` AS `upload_extension`,
`uploads`.`path` AS `upload_path`
FROM `news_articles`
LEFT JOIN `news_articles_tags` ON news_articles_tags.news_article_id = news_articles.id
LEFT JOIN `tags` ON news_articles_tags.tag_id = tags.id
LEFT JOIN `news_articles_news_categories` ON news_articles_news_categories.news_article_id = news_articles.id
LEFT JOIN `news_categories` ON news_articles_news_categories.news_category_id = news_categories.id
LEFT JOIN `news_articles_uploads` ON (news_articles_uploads.news_article_id = news_articles.id AND news_articles_uploads.order = 0)
LEFT JOIN `uploads` ON news_articles_uploads.upload_id = uploads.id
WHERE (news_categories.slug IN ("category-one","category-two","category-three","category-four","category-five")) AND (news_articles.published = 1)
GROUP BY `news_articles`.`id`
ORDER BY `news_articles`.`lead_article` DESC, `news_articles`.`created` DESC LIMIT 20;

问题是查询运行时速度很慢,而且在繁忙期间 CPU 使用率会变得非常失控!

这是上述查询的解释(右键单击在新选项卡中打开以查看完整大小):

Explain result for the above query

您可以在此处找到架构:http://pastie.org/private/qoe2qo16rbqr5mptb4bug

服务器运行 MySQL 5.1.55,网站使用 Zend Framework 执行查询和 PHP 5.2.8。

据我所知,我已经查看了 MySQL 慢速查询日志并添加了缺失的索引,但查询仍然显示需要 1-3 秒才能执行。如果有人有任何想法,我将非常感激。提前致谢。

最佳答案

由于您的“WHERE”子句最初包含“AND”用于您的新闻类别一个指定的列表,它将强制连接作为 INNER 连接到达那里,而不是 LEFT JOIN。另外,我会尝试添加“STRAIGHT_JOIN”子句。这通常会迫使引擎按照具体说明的顺序进行加入,而不是试图自己考虑您的替代方案...尤其是当其他表更多的是“查找”引用时。

我也会按照 Jordan 的建议应用索引。

SELECT STRAIGHT_JOIN
NA.*,
GROUP_CONCAT(DISTINCT tags.title) AS `tags`,
GROUP_CONCAT(DISTINCT tags.id) AS tag_ids,
GROUP_CONCAT(DISTINCT NC.title) AS news_categories,
GROUP_CONCAT(DISTINCT NC.id) AS news_category_ids,
GROUP_CONCAT(DISTINCT NC.slug) AS news_category_slugs,
NAUp.`caption` AS upload_caption,
Up1.`title` AS upload_title,
Up1.`basename` AS upload_basename,
Up1.`extension` AS upload_extension,
Up1.`path` AS upload_path
FROM
news_articles NA
INNER JOIN news_articles_news_categories NACats
ON NA.id = NACats.news_article_id

INNER JOIN news_categories NC
ON NACats.news_category_id = NC.id
AND NC.slug IN ( "category-one",
"category-two",
"category-three",
"category-four",
"category-five" )


LEFT JOIN news_articles_tags NATags
ON NA.ID = NATags.news_article_id

LEFT JOIN tags
ON NATags.tag_id = tags.id

LEFT JOIN news_articles_uploads NAUp
ON NA.ID = NAUp.news_article_id
AND NAUp.order = 0

LEFT JOIN uploads Up1
ON NAUp.upload_id = Up1.id

WHERE
NA.Published = 1
GROUP BY
NA.ID
ORDER BY
NA.lead_article DESC,
NA.created DESC
LIMIT 20;

关于mysql - 使用许多 LEFT JOIN 提高 SQL 查询的性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9427728/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com