针对标签上的多对多连接优化 MySQL 查询
Posted
技术标签:
【中文标题】针对标签上的多对多连接优化 MySQL 查询【英文标题】:Optimize MySQL query for Many-To-Many Join on tags 【发布时间】:2012-10-03 08:50:12 【问题描述】:我需要选择链接到特定标签的所有文章,但我还想要与每篇文章关联的所有其他标签。凭借我有限的 SQL 知识,我进行了以下 mysql 查询,该查询有效,但似乎效率不高。
SELECT a.id, a.name, c.id AS topic_id, c.name AS topic, GROUP_CONCAT(t.id) AS tag_ids, GROUP_CONCAT(t.name) AS tags, a.description
FROM tag t
LEFT JOIN artifacts_tags j ON t.id = j.tag_id
LEFT JOIN artifact a ON a.id = j.artifact_id
LEFT JOIN topic c ON c.id = a.topic_id
LEFT JOIN artifacts_tags aj ON a.id = aj.artifact_id
LEFT JOIN tag ts ON ts.id = aj.tag_id
WHERE ts.slug = 'summer'
AND a.is_public = 1
GROUP BY a.id
如果有人能提出更有效的查询,我将不胜感激。
实际上,我还需要类似的标签(所有标签都属于带有 slug 'summer' 的标签所属的主题),但我有另一个查询。如果我可以使用相同的查询获得类似的标签会更好,但我不知道如何。表tag
与topic
表具有多对一关系。
【问题讨论】:
您如何衡量效率?如果查询执行您想要的操作并在合理的时间内执行,并且您可以轻松理解和修改您的查询,那么它如何更有效?也就是说,在我看来,您可以将 LEFT 替换为 INNER 连接 - 但这取决于您的数据库内容和语义。 @AlexMonthy 你是对的。我应该使用 INNER 连接。谢谢 【参考方案1】:非确定性分组: SQL 检索既不在聚合函数中也不在 GROUP BY 表达式中的列,因此这些值在结果中将是不确定的。
GROUP BY 在不同的表上: 这将强制使用临时表和文件排序,这可能是一个巨大的性能问题,并且会消耗大量内存和磁盘上的临时空间。
【讨论】:
在这种情况下,SELECT 列表中的所有列都由a.id
(表article
的主键)确定,因此查询返回确定性结果。以上是关于针对标签上的多对多连接优化 MySQL 查询的主要内容,如果未能解决你的问题,请参考以下文章