JOIN是比几个查询速度更快的查询? (您运行主查询,然后根据您的主要查询的结果运行很多其他选择)
我这么问是因为加入他们会变得复杂了很多我的应用程序的设计
如果他们更快,任何人都可以通过近似非常粗略多少? 如果是1.5倍我不在乎,但如果它的10倍,我想我做的。
JOIN是比几个查询速度更快的查询? (您运行主查询,然后根据您的主要查询的结果运行很多其他选择)
我这么问是因为加入他们会变得复杂了很多我的应用程序的设计
如果他们更快,任何人都可以通过近似非常粗略多少? 如果是1.5倍我不在乎,但如果它的10倍,我想我做的。
这是太含糊,让您与您的具体情况的解答。 这取决于很多事情。 杰夫阿特伍德(这个网站的创始人)其实写这个 。 在大多数情况下,不过,如果你有正确的指标,你正确地做你的加入它通常会以更快的速度做1个旅行比数。
对于内部联接,一个查询是有道理的,因为你只能得到匹配的行。 对于左连接,多个查询要好得多......看看下面的基准我做:
5单查询加盟
查询:8.074508秒
结果大小:2268000
5个查询一行
合并查询时间:0.00262秒
结果大小:165(6 + 50 + 7 + 12 + 90)
。
请注意,我们得到相同的结果在两种情况下(6×50×7×12×90 = 2268000)
左连接使用成倍加大内存冗余数据。
如果你只能做一个连接两个表的内存限制可能不会那么糟糕,但一般三个或更多,并且变得值得不同的查询。
作为一个侧面说明,我的MySQL服务器是在身旁,我的应用程序服务器...所以连接时间是可以忽略不计。 如果你的连接时间是秒,那么也许还有一个好处
坦率
其实,我来到了这个问题寻找答案自己,阅读给定的答案后,我只能同意,比较DB的最佳方式查询的性能,是因为有只是很多变数获得真实世界的数字来加以考虑但是,我也认为他们之间比较的数字,不会产生任何好的在几乎所有情况下。 我的意思是,这些数字应该始终以可接受的数量进行比较,并绝对不会相互比较。
我可以理解,如果查询的一种方式需要说0.02秒,另一个需要20秒,这是一个巨大的差异。 但是,如果查询的一种方式需要什么0.0000000002秒,另外一个需要0.0000002秒? 在这两种情况下的一种方法是比另一个更快的高达1000倍,但它确实还是“高达”在第二种情况下?
底线是我亲眼所见:如果表现良好,去为简单的解决方案。
做了一个快速测试从50,000列的表中选择一个行并从10万行的表有一个行加入。 基本上,看起来像:
$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);
这两种选择方法把3.7秒50000读取,而在连接了2.0秒我在家慢计算机上。 INNER JOIN和LEFT JOIN没有有所作为。 读取多行(例如,使用SET)产生类似的结果。
构建两个单独的查询和连接,然后他们每个人的时间 - 没有什么帮助比现实世界的数字的详细。
那么就再好不过 - 添加“解释”对每个查询的开始。 这将MySQL是多少使用子查询来回答您的数据请求,以及如何被扫描的每个查询多行告诉你。
根据对比较复杂开发数据库的复杂性,它可能是简单的做很多选择通话。
尝试运行对阵双方一些数据库统计JOIN和多进行选择。 看看是否在您的环境中的连接的速度更快/比SELECT慢。
再说,如果将其更改为一个连接就意味着额外的天/周/ dev的工作一个月,我会多坚持的SELECT
干杯,
BLT
真正的问题是: 做这些记录有一个一对一的关系还是一个一对多的关系 ?
TLDR答案:
如果一个人对一,使用JOIN
语句。
如果一个对许多人来说,使用一个(或多个) SELECT
与服务器端代码优化语句。
为什么以及如何使用选择需要优化
SELECT
“荷兰国际集团(与多个查询,而不是连接)上大组的基础上的一对多的关系产生一个最佳效率的记录,如JOIN
” ING具有指数内存泄漏问题。 抓住所有的数据,然后使用一个服务器端脚本语言来梳理出来:
SELECT * FROM Address WHERE Personid IN(1,2,3);
结果:
Address.id : 1 // First person and their address
Address.Personid : 1
Address.City : "Boston"
Address.id : 2 // First person's second address
Address.Personid : 1
Address.City : "New York"
Address.id : 3 // Second person's address
Address.Personid : 2
Address.City : "Barcelona"
在这里,我让所有的记录,在一个select语句。 这是优于JOIN
,这会得到一小群的这些记录,一次一个,因为另一个查询的子组件。 然后我分析它与服务器端代码,看起来像...
<?php
foreach($addresses as $address) {
$persons[$address['Personid']]->Address[] = $address;
}
?>
当不使用JOIN的优化
JOIN
“荷兰国际集团一大群的基于一对一的关系相比较,以多个单一记录产生一个最佳效率的记录SELECT
语句,一前一后,其简单地获得下一个记录类型。
但JOIN
与一个一对多的关系越来越记录时是低效的。
例如:数据库博客有兴趣,博文,标签和注释的3个表。
SELECT * from BlogPost
LEFT JOIN Tag ON Tag.BlogPostid = BlogPost.id
LEFT JOIN Comment ON Comment.BlogPostid = BlogPost.id;
如果有1个博文,2个标签和2个评论,你会得到类似的结果:
Row1: tag1, comment1,
Row2: tag1, comment2,
Row3: tag2, comment1,
Row4: tag2, comment2,
请注意,每个记录是如何复制的。 好了,所以,2篇评论和2个标签是4行。 如果我们有4条评论和4个变量? 你没有得到8行 - 你会得到16行:
Row1: tag1, comment1,
Row2: tag1, comment2,
Row3: tag1, comment3,
Row4: tag1, comment4,
Row5: tag2, comment1,
Row6: tag2, comment2,
Row7: tag2, comment3,
Row8: tag2, comment4,
Row9: tag3, comment1,
Row10: tag3, comment2,
Row11: tag3, comment3,
Row12: tag3, comment4,
Row13: tag4, comment1,
Row14: tag4, comment2,
Row15: tag4, comment3,
Row16: tag4, comment4,
添加更多的表,更多的记录,等等,问题会很快膨胀到数百都充满主要是冗余的数据行。
做这些重复的费用吗? 内存(在SQL服务器和尝试删除重复的代码)(SQL服务器和代码服务器之间)和网络资源。
来源: https://dev.mysql.com/doc/refman/8.0/en/nested-join-optimization.html ; https://dev.mysql.com/doc/workbench/en/wb-relationship-tools.html
根据我的经验,我发现它通常更快地运行多个查询,检索大型数据集时尤其如此。
当从其他应用程序,比如PHP数据库交互,还有超多一趟到服务器的参数。
还有其他的方法来限制对服务器进行往返次数,仍然运行多个查询,常常不仅速度更快,而且使应用程序更易于阅读 - 比如mysqli_multi_query。
我不是新手,当涉及到SQL,我认为这是开发商的倾向,特别是大三学生花了很多时间试图写得很巧妙加入,因为他们看起来聪明,而实际上有聪明的方法来提取数据看简单。
最后一段是个人意见,但我希望这有助于。 但谁说,你应该基准我不与他人同意。 这两种方法都不是万能的。
它会更快的吞吐量方面? 大概。 但它也有可能同时锁定多个数据库对象(取决于您的数据库和架构上),从而降低了并发性。 在我的经验,人们往往通过“减少数据库往返”的说法误导时,在大多数OLTP系统的现实,其中数据库是在同一个局域网上,真正的瓶颈是很少的网络。
这个问题是旧的,但缺少一些基准。 我JOIN基准针对其竞争对手的2:
WHERE IN(...)
或等效 其结果是显而易见的:在MySQL, JOIN
快得多 。 N + 1级的查询可以急剧下降的应用程序的性能:
也就是说,除非你选择了很多指向一个非常小的数目的不同,国外的记录记录。 这里是极端情况下的基准:
这是不太可能在一个典型的应用程序的情况发生,除非你加入一个一对多的关系,在这种情况下,外键在其他表,你复制的主表中的数据很多次。
带走:
JOIN
请参阅我的文章中了解更多信息。
这里是100个有用的查询的链接,这些在Oracle数据库进行测试,但记得SQL是一种标准,甲骨文之间有什么不同,MS SQL服务器,MySQL和其他数据库的SQL方言:
http://javaforlearn.com/100-sql-queries-learn/
有几个因素,这意味着没有二进制的答案。 什么是最好的性能问题取决于您的环境。 顺便说一句,如果你选择单用标识符不是亚秒级的东西可能是错误的配置。
真正的问题是你怎么想访问数据。 单选择支持后期绑定。 例如,如果你只想员工信息,您可以从雇员表中选择。 外键关系可以用来在稍后的时间,并根据需要获取相关资源。 该选择将已经有一个关键点,以使他们应该是非常快的,你只需要获取你所需要的。 网络延迟必须加以考虑。
加入会检索所有数据的一次。 如果您正在生成报告或填充一个网格,这可能正是你想要的。 编译和optomized联接只是会比在这种情况下单选择速度更快。 请记住,特设连接可能不那么快 - 你应该编译它们(成一个存储过程)。 速度答案取决于执行计划,详细说明究竟哪些步骤,需要DBMS检索数据。
你是否应该使用联接首先是关于是否参加有意义 。 只有在这一点上是性能甚至一些被考虑,因为几乎所有的其他情况下会导致性能显著恶化 。
性能差异将主要依赖于如何与您查询的是信息。 加入工作,而且他们很快时,数据是有关你的东西指标正常,但他们往往会造成一定的冗余,比有时需要更多的结果。 如果你的数据集没有直接的关系,在一个查询中坚持它们会引发什么叫做笛卡尔积(基本上,行的所有可能的组合),这是几乎从来没有你想要的东西。
这通常是由多到一个一对多的关系引起的。 例如, HoldOffHunger的回答中提到上岗,标签和注释的单个查询。 因为是标签......但标签是无关的评论评论都涉及到一个职位。
+------------+ +---------+ +---------+
| comment | | post | | tag |
|------------|* 1|---------|1 *|---------|
| post_id |-----| post_id |-----| post_id |
| comment_id | | ... | | tag_id |
| user_id | | | | ... |
| ... | | | | ... |
+------------+ +---------+ +---------+
在这种情况下,它是明确更好地为这是至少两个单独的查询。 如果你尝试加入标签和注释,因为有两者之间并没有直接的关系,你最终的标签和注释的每一个可能的组合。 many * many == manymany
。 除此之外,由于职位和标签无关,你可以做这两个查询并行,导致潜在的收益。
让我们考虑一个不同的场景,但:你要连接到文章的评论,而评论者的联系信息。
+----------+ +------------+ +---------+
| user | | comment | | post |
|----------|1 *|------------|* 1|---------|
| user_id |-----| post_id |-----| post_id |
| username | | user_id | | ... |
| ... | | ... | +---------+
+----------+ +------------+
这是你应该考虑加入。 除了是一个更自然的查询,大多数数据库系统(包括MySQL)有很多聪明人把大量的辛勤工作为优化查询,就像它。 对于单独的查询,因为每个查询依赖于以前的一个结果,查询不能并行进行,总时间变得不只是查询的实际执行时间,而且花费的时间获取结果,过筛通过他们的ID为下一个查询,联排在一起,等等。
是的,使用一个查询连接会更快。 虽然不知道要查询的表的关系,你的数据集的大小,或在主键,这几乎是不可能说快多少。
为什么这两种方案不是检验出来,那么你肯定知道...