JOIN 在 MySQL 中是如何工作的?
Posted
技术标签:
【中文标题】JOIN 在 MySQL 中是如何工作的?【英文标题】:How does JOIN work in MySQL? 【发布时间】:2011-12-26 23:39:58 【问题描述】:虽然问题标题与许多讨论重复,但我没有找到这个问题的答案:
考虑对标准化的标签表进行简单连接
SELECT tags.tag
FROM tags
INNER JOIN tag_map
ON tags.tag_id=tag_map.tag_id
WHERE article_id=xx
JOIN
是否与整个标签表和 tag_map 一起使用,然后过滤创建的 (JOIN
ed) 表以查找带有文章 ID 的 WHERE
子句的行
OR JOIN
只会加入 tag_map 表中 article_id=xx 的行?
后一种方法应该会快很多!
【问题讨论】:
In what order are mysql JOINs evaluated?的可能重复 【参考方案1】:据我所知,它将在生成的 JOINed 表上显式执行 WHERE。 (免责声明:MySQL 可能会在某些情况下对此进行优化,我不知道)。
要强制执行后一种行为并首先执行 WHERE,您可以在 JOIN ON 语句中添加一个额外的过滤器:
SELECT tags.tag
FROM tags
INNER JOIN tag_map
ON tags.article_id=xx
AND tags.tag_id=tag_map.tag_id
WHERE article_id=xx
【讨论】:
@Ali 和 Andrew,我不同意首先执行 JOIN。看看我的回答。 JOIN 基本上准备了表的关系。然后,索引将得到实施。查看具有数百万条记录的表,并且在 tableA 和 tableB 之间,您知道将找到记录。真的会先预加入所有记录吗? 您将连接返回的内容与实现方式的描述混淆了。阅读有关连接优化的 MySQL 手册。或者在被问和回答时甚至存在许多重复。【参考方案2】:联接仅适用于那些从第一个返回记录的表的 WHERE 子句中限定的记录。也就是说,您正在对 tag_map 进行联接,但您的 where 子句未指定“Article_ID”与哪个别名相关联.通常最好始终使用来自的表名或别名来限定您的字段。
因此,如果 article_id 来自 TAGS,那么它将首先将该列表视为主要记录集,如果存在则使用索引进行优化并返回一个小记录集。从此,join 被应用到 tag_map 并且会抓取所有匹配 join "ON" 条件的记录。
只是为了澄清一些事情。如果首先应用 JOIN,则在 WHERE 子句优化之前,查询将永远持续下去。连接基本上在记录选择实际发生之前准备好关系。因此,显示将使用的索引的执行计划。
【讨论】:
【参考方案3】:这取决于引擎。许多数据库引擎的早期版本会先生成连接结果,然后再进行过滤。较新版本的引擎会生成一个执行计划,以实现最快的结果。必须使用数据库引擎进行测试,检查您的版本/数据库的执行计划,以找到“最好的”
【讨论】:
【参考方案4】:假设它是简单的或内连接:
答案是:在关系模型中,第一个答案是正确的,它创建一个表,其中包含第一个表中的每一行与第二个表中的每一行交叉,因此如果第一个有 N 行,第二个有 M,它将使用 NxM 创建一个表,然后消除那些条件不匹配的表。
现在,这是数学模型,但在实现中,取决于引擎,它将使用一些更智能的方式,通常选择一个看起来更快的表,然后使用希望索引的连接字段从那里连接。但这取决于引擎之间:有很多文档(谷歌它)和一些人,包括这个答案的海报,被付费用于优化连接查询......
如果是 MYSQL(刚刚注意到标签),您可以使用以下语法:
EXPLAIN [EXTENDED] SELECT select_options
正如here 解释的那样,MYSQL 会告诉你它将如何执行这样的查询。它比阅读文档更快。
【讨论】:
@Robert Koritnik 谢谢,这是一个令人困惑的错字。 不用担心。既然很明显,我敢自己纠正它,否则我会发表评论让你澄清它。【参考方案5】:您可以随时查看执行计划,了解您的查询是如何逐步执行的。在 MySQL 中,我不知道它是否可以使用任何第三方工具以图形方式呈现(就像您可以在 MS SQL 上使用 Management Studio 开箱即用一样),但您仍然可以使用 explain
语言结构来检查它。检查文档。
不知道您的表架构
如果article_id
属于表tags
,则根本不扫描tag_map
表,除非FK 表中的连接列可以为空。
如果article_id
已被索引(即主键),则正在扫描索引...
等等……
我想说的是,我们需要您的表架构定义来告诉您一些细节。我们无法知道您的架构是如何工作的。
【讨论】:
以上是关于JOIN 在 MySQL 中是如何工作的?的主要内容,如果未能解决你的问题,请参考以下文章