JOIN查询是否比多个查询快?(运行主查询,然后根据主查询的结果运行许多其他select)
我这么问是因为加入它们会使我的应用程序的设计复杂化
如果它们快了,有人能大致估计出快了多少吗?如果是1.5倍,我不在乎,但如果是10倍,我就在乎。
JOIN查询是否比多个查询快?(运行主查询,然后根据主查询的结果运行许多其他select)
我这么问是因为加入它们会使我的应用程序的设计复杂化
如果它们快了,有人能大致估计出快了多少吗?如果是1.5倍,我不在乎,但如果是10倍,我就在乎。
当前回答
这里有100个有用的查询链接,这些都是在Oracle数据库中测试的,但记住SQL是标准的,Oracle, MS SQL Server, MySQL和其他数据库之间的区别是SQL方言:
http://javaforlearn.com/100-sql-queries-learn/
其他回答
实际上,我自己也在寻找这个问题的答案,在阅读了给出的答案后,我只能同意比较DB查询性能的最佳方法是获得真实世界的数字,因为有太多的变量需要考虑,但是,我也认为比较它们之间的数字在几乎所有情况下都不会有好的结果。我的意思是,这些数字应该始终与一个可接受的数字进行比较,而绝对不是相互比较。
我可以理解,如果一种查询方式需要0.02秒,而另一种需要20秒,这是一个巨大的差异。但是,如果一种查询方式需要0.0000000002秒,而另一种需要0.0000002秒呢?在这两种情况下,一种方式比另一种方式快1000倍,但在第二种情况下,它真的仍然“惊人”吗?
就我个人而言,底线是:如果它表现良好,就寻求简单的解决方案。
对于内部连接,单个查询是有意义的,因为您只获得匹配的行。 对于左连接,多个查询要好得多……看看下面我做的基准测试:
5个join的单个查询 查询:8.074508秒 结果大小:2268000 一行5个查询 组合查询时间:0.00262秒 结果大小:165 (6 + 50 + 7 + 12 + 90)
.
注意,我们在这两种情况下得到了相同的结果(6 x 50 x 7 x 12 x 90 = 2268000)
左连接使用指数级的冗余数据内存。
如果只连接两个表,内存限制可能没有那么糟糕,但通常是三个或三个以上,因此值得进行不同的查询。
顺便说一句,我的MySQL服务器就在我的应用服务器旁边…所以连接时间可以忽略不计。如果您的连接时间以秒为单位,那么可能会有好处
弗兰克
这太模糊了,不能给你一个与你的具体情况相关的答案。这取决于很多因素。Jeff Atwood(这个网站的创始人)确实写过这个。不过,在大多数情况下,如果你有正确的索引,并且正确地执行join,那么执行一次旅行通常比执行几次旅行要快。
是否应该使用连接首先是关于连接是否有意义。只有在这种情况下,性能才会被考虑,因为几乎所有其他情况都会导致明显更差的性能。
性能差异很大程度上取决于所查询信息的相关性。联接是有用的,当数据相关且索引正确时,联接速度很快,但它们通常会导致一些冗余,有时结果比需要的多。如果您的数据集不是直接相关的,那么将它们放在一个查询中将导致所谓的笛卡尔积(基本上是所有可能的行组合),这几乎不是您想要的结果。
这通常是由多对一对多关系引起的。例如,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.
做了一个快速测试,从50,000行表中选择一行,并连接100,000行表中的一行。基本上是这样的:
$id = mt_rand(1, 50000);
$row = $db->fetchOne("SELECT * FROM table1 WHERE id = " . $id);
$row = $db->fetchOne("SELECT * FROM table2 WHERE other_id = " . $row['other_id']);
vs
$id = mt_rand(1, 50000);
$db->fetchOne("SELECT table1.*, table2.*
FROM table1
LEFT JOIN table1.other_id = table2.other_id
WHERE table1.id = " . $id);
在我的家用慢速电脑上,two select方法读取50,000次需要3.7秒,而JOIN方法需要2.0秒。INNER JOIN和LEFT JOIN没有区别。获取多行(例如,使用IN SET)会产生类似的结果。