我们应该避免使用LEFT JOIN

问题描述:

我对过去7天的问题感到困惑。我搜索了很多,也探讨了SO,但找不到满意的答案。我们应该避免使用LEFT JOIN

我想澄清我的概念左加入。因为我们知道LEFT JOIN从右表中返回所有的值,并通过右表返回加入的值(通过外键)。现在,如果右表中有10个值指向左表中的主键,那么LEFT JOIN将从右表中重复第一个表值10次,同时给出右表中的值。这只是一个例子。它是否有效,或者我不应该担心它吗?

这里是重复的示例值

enter image description here

我强调重复的值。 其实,我有一个表,我想用LEFT JOIN从同一个表中获取子注释。行可能在100s而不是在1000s。我有相关领域的索引。所以,请引导我(记住LEFT JOIN从左起反复排列的本地行为),我应该担心它吗?并且它是否大部分使用?

性能是否有效?或者我应该不担心吗?

这是一个我只能指回自己的问题。这些问题只是非常主观的,不能以一般方式回答。

这也是为什么你没有在谷歌上找到一个简单的答案的原因。

我可以给出的最佳答案是:与您的数据库性能顾问联系并与她讨论问题。在向她提供足够的信息并访问测试平台后,她应该能够明确地回答您的问题。

它权衡的问题...

首先,贵外连接的查询执行呢?鉴于你展示的例子,它应该,如果你使用索引字段来映射外键关系。使用EXPLAIN来确定您是否确实在使用索引字段,并在需要时优化查询。

如果查询本身速度很快,那么下一个问题是您要在数据库和应用程序服务器之间发送比您需要的数据略多一些的数据 - 来自左侧表的重复数据。虽然不理想,但我怀疑你可以衡量差异,除非你真的在大量工作。如果您要发送数百条记录,并且每个记录有几个额外的字节,那么如果网络无法跟上,那么您的问题会比外部连接多得多。

最后,你必须考虑替代方案。使用外部联接,即使由于联接而稍慢,您也可以在单个查询中检索所有匹配的数据。另一种方法是获取所有父记录,循环遍历它们并找到匹配的子项。这将远远慢得多 - 而不是一个查询,您将执行数十个或数百个(根据您处理“数百个,而不是数千个记录”的语句)。每个查询都有开销,并且总之,开销可能远远超过额外的“加入”语句成本。

但是,找出最好的方法是使用像DBMonster这样的工具,加载一个测试数据库,其数据量比您以前想象的要多10倍,然后试用。

有关bandwith的最高性能解决方案是在一回合中获得标题,并在第二回合中获得所有的孩子。让他们留在记忆中,并自己加入。这通常是一个“坏主意”,因为它不能很好地扩展(想象一下,在单个服务器上的多个会话的内存要求都会对不断扩展的数据集执行此操作),但是如果可以保持数据集不变并且网络真的这不好,这是一个可行的选择。

最终答案:是的,你理解正确。这通常很好,但有一种方法。

如果我正确理解你,你所描述的只是一个左内连接的工作原理。

您是否必须使用左连接来获取子注释?是否有另一种方法可以使用?也许(这完全是关闭的,没有研究)使用1个查询来获得父注释,另一个查询子注释并将结果联合在一起?