join是为懒惰的人?

最近我和另一个开发者讨论过,JOINs(SQL)是无用的。 这在技术上是正确的,但他补充说,使用连接比在代码(C#或Java)中创build多个请求和链接表的效率要低。

对他来说,join是懒惰的人,不关心performance。 这是真的? 我们应该避免使用连接吗?

不,我们应该避免那些抱着如此令人难以置信的错误观点的开发商。

在许多情况下,数据库连接比通过客户端完成的任何事情快几个数量级,因为它避免了DB往返,DB可以使用索引来执行连接。

关于我的头,我甚至无法想象一个正确使用的连接会比等效的客户端操作慢的情况。

编辑:在一些罕见的情况下,自定义的客户端代码可以比直接的数据库连接更有效地完成任务(请参阅评论)。 但是这是个例外。

这听起来像你的同事会做一个没有SQL的文档数据库或键值存储。 哪些是自己很好的工具,很适合很多问题。

但是, 关系数据库对集合进行了大量优化。 有许多种方式基于连接来查询数据,这些连接比大量的往返旅程效率高得多。 这是rdbms的通用性来自哪里。 您也可以在nosql存储库中实现同样的function,但是您通常最终会build立适合于每种不同查询性质的独立结构。

总之:我不同意。 在RDBMS中,连接是基础 。 如果你不使用它们,那么你并没有把它用作RDBMS。

那么他在一般情况下是错的。

数据库能够使用各种方法进行优化,这些方法由优化器提示,表索引,外键关系以及可能的其他数据库供应商特定信息提供帮助。

不,你不应该。

数据库是专门devise来操纵数据集(显然是…)。 所以他们非常高效地做到这一点。 通过在自己的代码中进行本质上的人工join,他正试图接pipe专门为这项工作devise的东西。 他的代码与数据库中的代码一样高效的机会是非常遥远的。

顺便说一句,没有连接,使用数据库有什么意义? 他可能只是使用文本文件。

如果“懒惰”被定义为想写更less的代码的人,那么我同意。 如果“懒惰”被定义为想要拥有工具的人做他们擅长的事情,我同意。 所以如果他只是同意Larry Wall(关于优秀程序员的特性),那么我同意他的观点。

嗯,连接是关系数据库如何相互关联表。 我不知道他在做什么。

怎样才能使数据库调用比一次调用更有效率? 加上sql引擎在这样的事情上进行了优化。

也许你的同事懒得学习SQL。

是的你应该。

而你应该使用C ++而不是C#,因为性能。 C#是为懒惰的人。

不不不。 由于性能,您应该使用C而不是C ++。 C ++是为懒惰的人。

不不不。 由于性能,您应该使用程序集而不是C语言。 C是懒惰的人。

是的,我在开玩笑。 您可以在没有连接的情况下制作更快的程序,并且可以使程序使用更less的内存而无需连接。 但在很多情况下,你的开发时间比CPU时间和内存更重要。 放弃一点演出,享受你的生活。 不要为了小小的performance而浪费时间。 并告诉他:“你为什么不从你的地方到你的办公室?”

“这是技术性的真实” – 同样,SQL数据库是没有用的:当使用一堆CSV文件获得相同的结果并使用代码进行关联时,使用一个SQL数据库有什么意义? 嘿,任何抽象都是针对懒惰的人,让我们回到硬件上的机器编程吧! ;)

另外,他的断言在所有情况中都是不真实的,除了最复杂的情​​况之外:RDBMS经过大量优化以使JOIN 快速完成关系数据库pipe理系统,对不对?

我工作的最后一个公司也没有使用SQL连接。 相反,他们将这项工作转移到了devise为水平扩展的应用层。 这种devise的基本原理是避免在数据库层工作。 通常是数据库成为瓶颈。 它比数据库更容易复制应用程序层。 可能还有其他原因。 但这是我现在可以回想起来的。

是的,我同意在应用层完成的连接与由数据库完成的连接相比是低效的。 更多的networking通信也。

请注意,我没有采取坚决的立场避免SQL连接。

如果没有联系,您将如何将订单项目与订单相关联? 这是关系数据库pipe理系统的全部要点。 没有连接就没有关系数据,你也可以使用文本文件来处理数据。

听起来他不明白这个概念,所以他试图让它看起来毫无用处。 他是认为excel是数据库应用程序的同一types的人。 狠狠地揍他一顿,告诉他阅读更多关于数据库的资料。 通过C#进行多个连接并提取数据和合并数据是做错事情的错误方法。

我不明白“在SQL中join是无用的”的逻辑。 在处理数据之前过滤和限制数据是否有用? 正如其他响应者所说,这是数据库引擎所做的,应该是他们擅长的。

也许一个懒惰的程序员会坚持使用他们熟悉的技术,并由于非技术原因而放弃其他可能性。

我把它交给你决定。

我们来看一个例子:一个包含发票logging的表格,一个包含发票行项目logging的相关表格。 考虑客户伪代码:

 for each (invoice in invoices) let invoiceLines = FindLinesFor(invoice) ... 

如果您有10万条发票,每条10行,则此代码将从100万张表中查找10条发票行,并且将执行10万次。 随着表格尺寸增加,select操作的数量增加, 并且每个select操作的成本增加。

由于计算机速度很快,如果您有几千条或更less的logging,您可能不会注意到两种方法之间的性能差异。 由于成本的增长不仅仅是线性的,随着logging数量的增加(比如说成千上万),你会开始注意到一个差异,随着数据集的规模增长,这个差异将变得越来越小。

然而,join。 将使用表的索引并合并两个数据集。 这意味着你正在有效地扫描第二个表,而不是随机访问它N次。 如果定义了外键,则数据库已经在内部存储的相关logging之间具有链接。

想象一下你自己做这个。 你有一个按字母顺序排列的学生名单和一个包含所有学生成绩报告的笔记本(每个class级一页)。 笔记本按学生姓名顺序排列,顺序与列表相同。 你想如何继续?

  1. 从列表中读取一个名字。
  2. 打开笔记本。
  3. find学生的名字。
  4. 阅读学生的成绩,翻页,直到到达下一个学生或最后一页。
  5. closures笔记本。
  6. 重复。

要么:

  1. 打开笔记本到第一页。
  2. 从列表中读取一个名字。
  3. 从笔记本上读取这个名字的任何等级。
  4. 重复步骤2-3,直到完成
  5. closures笔记本。

听起来像是“ 我可以写得更好 ”的经典案例。 换句话说,他正在看到一些他认为是脖子上的痛苦(用SQL编写一堆连接),并说:“我确信我可以写得更好,并获得更好的性能”。 你应该问他是否更聪明,和b)比在Oracle或SQL Server优化代码中深入人心的典型人更受教育。 赔率是他不是。

他肯定是错的。 虽然在C#或Java等语言中有数据操作的明确优点,但由于SQL本身的性质,连接在数据库中是最快的。

SQL保持详细的有关数据的统计信息,如果你已经正确创build了你的索引,可以很快find几百万条logging。 除了这个事实,为什么你要把所有的数据都拖到C#中来完成一个连接呢?

当你需要迭代地做一些事情时,使用C#的优点就会起作用。 如果你需要为每一行做一些function,那么在C#中这样做可能会更快,否则,在DB中优化连接数据。

我会说,我已经遇到了一个更快地打破查询,并在代码中进行连接的情况。 这就是说,只有一个特定版本的MySQL,我必须这样做。 其他一切,数据库可能会更快(请注意,您可能不得不优化查询,但它仍然会更快)。

我怀疑他对使用哪些数据库的看法有限。 一种最大化性能的方法是将整个数据库读入内存。 在这种情况下,您可能会获得更好的性能,并且您可能想要为提高效率而进行连接。 然而,这不是真的使用数据库,作为数据库恕我直言。

不,不仅在数据库代码中更好地优化了连接C#/ Java; 但是通常可以应用几种过滤技术,这产生更好的性能。

他错了,连接是主pipe程序员使用的。 可能有一些有限的情况下,他提出的方法是更有效的(在我可能会使用Documant数据库),但我不能看到它,如果你有任何数量的欺骗性。 例如,采取这个查询:

 select t1.field1 from table1 t1 join table2 t2 on t1.id = t2.id where t1.field2 = 'test' 

假设你在表1中有1000万条logging,在表2中有100万条logging。 假设表1中有900万条logging符合where条款。 假设其中只有15个在表2中。 你可以运行这个sql语句,如果索引正确,将花费毫秒,并在networking上返回15条logging,只有1列数据。 或者,您可以发送一千万条logging和两列数据,并通过networking分别向另一列数据发送另外一百万条logging,并将它们组合到networking服务器上。

或者,当然,如果您的数据量和数据量不断变化,那么您可以始终将数据库的全部内容保留在Web服务器上,这实在是太愚蠢了。 如果你不需要关系数据库的特性,那就不要使用它。 但是,如果你这样做,然后正确使用它。

在我作为软件开发人员的职业生涯中,我经常听到这个说法。 几乎每次都说明,提出这个要求的人对关系数据库系统,他们的工作方式以及这种系统的使用方式知之甚less。

是的,如果使用不当 ,联接似乎是无用的甚至是危险的。 但是,当以正确的方式使用时,数据库实现有很大的潜力来执行优化,并“帮助”开发人员最有效地检索正确的结果。

不要忘记,使用JOIN您可以告诉数据库您希望数据相互关联的方式,从而为数据库提供更多关于您正在尝试执行的操作的信息,从而使其能够更好地满足您的需求。

所以答案肯定是:不, JOINS根本就没用!

只有在应用程序中不经常使用的情况下(连接中所有表的所有行由查询返回时),这才是“技术上真实的”。 在大多数查询中,仅返回每个表的一小部分行。 数据库引擎通常使用索引来消除不需要的行,有时甚至不读取实际行,因为它可以使用存储在索引中的值。 数据库引擎本身是用C,C ++等编写的,至less和开发人员写的代码一样高效。

除非我严重误解,否则这个问题的逻辑是非常有缺陷的

如果每个A有20行B,那么A中的1000行就意味着B中有20k行。除非有许多包含映射的20k行的表“AB”,否则B中不能有100行。

因此,要获得关于100 B行中哪20个映射到每个A行的所有信息,也可以使用AB表。 所以这可能是:

  • 3个100,1000和20k行的结果集和一个客户端JOIN
  • 一个JOINed A-AB-B结果集有20k行

所以,当你检查数据时,客户端中的“JOIN”会添加任何值。 不是说这不是一个坏主意。 如果我从数据库中检索到一个对象,那么将它分解成单独的结果集更有意义。 对于一个报告types的调用,我几乎总是把它压平成一个。

无论如何,我认为几乎没有这个量级的交叉连接的用处。 这是一个不好的例子。

你必须join某个地方,这就是RDBMS擅长的。 我不想和任何认为可以做得更好的客户端代码猴子合作。

事后:

要join客户端需要持久对象,如DataTables(以.net的forms)。 如果你有一个扁平的结果集,它可以通过像DataReader一样轻的东西来消费。 高容量=用于避免数据库JOIN的大量客户端资源。