JOIN 比两个 sql 查询效率低吗?
Posted
技术标签:
【中文标题】JOIN 比两个 sql 查询效率低吗?【英文标题】:Is JOIN less efficient than two sql queries? 【发布时间】:2017-05-27 02:42:53 【问题描述】:我有两张桌子
表 A(主键为 ID) id \firstname\lastname\zip\state
表 B some_field\ 公司名称 \ zip \ id
我需要使用 Table B 中的 id 获取与 id 关联的名字和姓氏(注意这与 Table A 中的 id 相同)
我在表 A 和表 B 上做了一个 JOIN,这样我就可以得到名字和姓氏
我的一个朋友说我不应该以这种方式使用 JOIN,我应该只做两个单独的查询。这有意义吗?
JOIN 是否会导致进程比两个单独的查询慢?两个单独的查询怎么会比一个查询快?
【问题讨论】:
看到这个帖子:***.com/questions/1067016/… 名字和姓氏只是 TableA 的一部分。那为什么要加入TableB.. 连接查询可能对数据库造成更多负担,但由于网络延迟等原因,总体上花费的时间更少。 使用正确索引字段的连接查询肯定比执行两个单独的查询要少得多。主键是自动索引的,因此连接的结果是一次查找。加入这两个表是正确的做法。但是是的,问题的语言有些可疑,如果您不需要表 B 中的字段,请不要无缘无故地加入它。 【参考方案1】:问:这有意义吗?
A:不,没有正当理由,这是没有意义的。
问:JOIN 是否会导致进程比两个单独的查询慢?
A:是的,有些事情会使连接变慢,所以我们不能排除这种可能性。我们不能笼统地说“两个单独的查询会更快”或“连接会更慢”。
正确索引的两个表的等值连接可能更有效。但是,最好通过实际执行语句、以预期的数据生产量以及观察和测量性能来衡量性能。
一些可能使连接变慢的事情...复杂的连接谓词(涉及包含在函数中的列、不等式比较、与OR
结合的复合谓词、涉及多个表,其中优化器具有更多连接路径和操作考虑提出一个执行计划。或者,一个产生hugh jass中间结果的连接,后来被一个GROUP BY折叠。(简而言之,可以编写一个使用连接操作的非常低效的语句。但是通常不是连接操作是罪魁祸首。这个列表只是一个样本,它不是一个详尽的列表。)
JOIN 是您描述的用例的规范模式。不清楚您的朋友为什么建议您避免 JOIN 操作。你的朋友给出了什么理由。
如果您的主要查询主要针对(不幸命名的)Table_B
,并且您希望从 Table_A
中查找 first_name 和 last_name,则 JOIN 适合此。
如果您只从Table_B
返回一行(或几行),那么另一个查询获取 first_name 和 last_name 的额外往返不会有问题。但是,如果您从 Table_B
返回数千个行,那么对 Table_A
执行数千个单独的单例查询将会降低性能和可伸缩性。
如果您的朋友担心Table_B
中的外键列中的值与Table_A
中的id
列中的值不匹配,或者外键列中有 NULL 值,您的朋友指出内部连接会阻止来自Table_B
的行被返回是正确的。
在这种情况下,我们将使用 outer 连接,因此即使未找到来自 Table_A
的匹配行,我们也可以返回来自 Table_B
的行。
您的朋友可能还担心 JOIN 操作的性能,可能是因为您的朋友因未定义合适的索引而被烧毁。
假设在Table_A
上存在合适的索引(带有前导列id
)。并且id
在Table_A
中是唯一的...那么在单列外键和单列主键之间进行简单等值连接的单个查询的性能可能比运行大量单独的语句。
或者,也许您的朋友担心 ORM 框架不成熟,它不能有效地处理连接查询返回的结果。
如果数据库的实现方式是两个表可以位于不同的数据库服务器上,那么使用 JOIN 将与该设计相悖。如果这是设计意图,即表的分离,那么应用程序也应该为两个表中的每一个使用单独的连接。
除非您的朋友可以提供避免 JOIN 操作的特定原因,否则我的建议是您忽略他的建议。
(必须有充分的理由避免 JOIN 操作。我怀疑您的朋友可能不了解关系数据库的工作原理。)
【讨论】:
【参考方案2】:在您的情况下,它没有任何大的区别,因为您只有一个 id
作为它的外键,无论如何它都有一个索引。由于它已编入索引,因此它会很高效,并且加入它是最好的。
根据你想要什么,领域是什么以及你想要完成什么等变得更加复杂。
所以,是的,你的情况没有太大的不同。
【讨论】:
这里有很多未知变量。你不能像这样一概而论。 如果Table_B
上的查询返回 15,000 行,那么 会有所不同。对于从 Table_B
返回的每一行,对数据库执行 15,000 条单独的语句(往返)以从 Table_A
获取一行可能非常缓慢。例如,如果我们只从Table_B
中检索几行,而Table_B
上没有WHERE 子句,并使用LIMIT 1
截断结果集,则运行单独的查询以从@987654328 中获取一行@ 可能比准备一个hugh jass 中间结果集更快。可能存在一些显着差异。以上是关于JOIN 比两个 sql 查询效率低吗?的主要内容,如果未能解决你的问题,请参考以下文章
关于SQL 查询效率问题 left join 改成 inner join union
sql inner join 与 left join和right join 执行效率上面有多大差别?