JOIN查询是否比多个查询快?(运行主查询,然后根据主查询的结果运行许多其他select)

我这么问是因为加入它们会使我的应用程序的设计复杂化

如果它们快了,有人能大致估计出快了多少吗?如果是1.5倍,我不在乎,但如果是10倍,我就在乎。


当前回答

根据我的经验,我发现运行几个查询通常更快,特别是在检索大型数据集时。

当与来自另一个应用程序(如PHP)的数据库交互时,到服务器的一次访问要比多次访问多。

还有其他方法可以限制访问服务器的次数,同时仍然运行多个查询,这些方法通常不仅更快,而且使应用程序更易于阅读—例如mysqli_multi_query。

当涉及到SQL时,我不是新手,我认为对于开发人员,尤其是新手来说,有一种趋势是花费大量时间试图编写非常聪明的连接,因为它们看起来很聪明,而实际上有一些聪明的方法来提取数据,看起来很简单。

最后一段是我的个人观点,但我希望这能有所帮助。我同意其他人的观点,尽管他们认为你应该进行基准测试。两种方法都不是灵丹妙药。

其他回答

根据我的经验,我发现运行几个查询通常更快,特别是在检索大型数据集时。

当与来自另一个应用程序(如PHP)的数据库交互时,到服务器的一次访问要比多次访问多。

还有其他方法可以限制访问服务器的次数,同时仍然运行多个查询,这些方法通常不仅更快,而且使应用程序更易于阅读—例如mysqli_multi_query。

当涉及到SQL时,我不是新手,我认为对于开发人员,尤其是新手来说,有一种趋势是花费大量时间试图编写非常聪明的连接,因为它们看起来很聪明,而实际上有一些聪明的方法来提取数据,看起来很简单。

最后一段是我的个人观点,但我希望这能有所帮助。我同意其他人的观点,尽管他们认为你应该进行基准测试。两种方法都不是灵丹妙药。

这个问题很老了,但是缺少一些基准。我对比了JOIN的两个竞争对手:

N + 1查询 2个查询,第二个查询使用WHERE IN(…)或等价的

结果很明显:在MySQL上,JOIN要快得多。N+1个查询会大大降低应用程序的性能:

也就是说,除非您选择了大量指向极少数不同的外部记录的记录。下面是极端情况下的基准测试:

在典型的应用程序中,这种情况不太可能发生,除非您正在连接一对多的关系,在这种情况下,外键在另一个表上,并且您多次复制主表数据。

导读:

对于*对1关系,总是使用JOIN 对于*对多的关系,第二个查询可能更快

更多信息请参阅我在Medium上的文章。

这太模糊了,不能给你一个与你的具体情况相关的答案。这取决于很多因素。Jeff Atwood(这个网站的创始人)确实写过这个。不过,在大多数情况下,如果你有正确的索引,并且正确地执行join,那么执行一次旅行通常比执行几次旅行要快。

实际上,我自己也在寻找这个问题的答案,在阅读了给出的答案后,我只能同意比较DB查询性能的最佳方法是获得真实世界的数字,因为有太多的变量需要考虑,但是,我也认为比较它们之间的数字在几乎所有情况下都不会有好的结果。我的意思是,这些数字应该始终与一个可接受的数字进行比较,而绝对不是相互比较。

我可以理解,如果一种查询方式需要0.02秒,而另一种需要20秒,这是一个巨大的差异。但是,如果一种查询方式需要0.0000000002秒,而另一种需要0.0000002秒呢?在这两种情况下,一种方式比另一种方式快1000倍,但在第二种情况下,它真的仍然“惊人”吗?

就我个人而言,底线是:如果它表现良好,就寻求简单的解决方案。

是否应该使用连接首先是关于连接是否有意义。只有在这种情况下,性能才会被考虑,因为几乎所有其他情况都会导致明显更差的性能。

性能差异很大程度上取决于所查询信息的相关性。联接是有用的,当数据相关且索引正确时,联接速度很快,但它们通常会导致一些冗余,有时结果比需要的多。如果您的数据集不是直接相关的,那么将它们放在一个查询中将导致所谓的笛卡尔积(基本上是所有可能的行组合),这几乎不是您想要的结果。

这通常是由多对一对多关系引起的。例如,HoldOffHunger的回答提到了一个关于帖子、标签和评论的查询。评论与一篇文章相关,标签也是如此。但是标签与注释无关。

+------------+     +---------+     +---------+
|  comment   |     |   post  |     |  tag    |
|------------|*   1|---------|1   *|---------|
| post_id    |-----| post_id |-----| post_id |
| comment_id |     | ...     |     | tag_id  |
| user_id    |     |         |     | ...     |
| ...        |     |         |     | ...     |
+------------+     +---------+     +---------+

在这种情况下,最好至少有两个独立的查询。如果您试图连接标记和注释,因为两者之间没有直接的关系,您最终会得到标记和注释的所有可能组合。许多*许多=许多许多。除此之外,由于帖子和标签是不相关的,您可以并行执行这两个查询,从而获得潜在的收益。

让我们考虑一个不同的场景:您希望将评论附加到一篇文章,以及评论者的联系信息。

 +----------+     +------------+     +---------+
 |   user   |     |  comment   |     |   post  |
 |----------|1   *|------------|*   1|---------|
 | user_id  |-----| post_id    |-----| post_id |
 | username |     | user_id    |     | ...     |
 | ...      |     | ...        |     +---------+
 +----------+     +------------+

This is where you should consider a join. Aside from being a much more natural query, most database systems (including MySQL) have lots of smart people put lots of hard work into optimizing queries just like it. For separate queries, since each query depends on the results of the previous one, the queries can't be done in parallel, and the total time becomes not just the actual execute time of the queries, but also the time spent fetching results, sifting through them for IDs for the next query, linking rows together, etc.