&引用;[MySQL]连接是邪恶的”卡尔·亨德森

&引用;[MySQL]连接是邪恶的”卡尔·亨德森,mysql,Mysql,Flickr的卡尔·亨德森(Cal Henderson)给出了答案。他简要地谈到了Django框架在查询中使用表联接的问题,并断言,“当达到一定规模时,您不会使用联接。”我希望Henderson对这方面了如指掌,但有人知道他的说法可能是什么原因吗?在一定的性能水平上,您非常关心需要移动磁盘头多少次才能满足查询。要通过连接将两条记录放在一起,您需要至少移动磁盘头两次,除非一条或两条记录完全保存在索引中,并且索引被缓存。(将列添加到索引中,以便满足查询所需的列从索引中出来是一种常见的技术,但索引元组

Flickr的卡尔·亨德森(Cal Henderson)给出了答案。他简要地谈到了Django框架在查询中使用表联接的问题,并断言,“当达到一定规模时,您不会使用联接。”我希望Henderson对这方面了如指掌,但有人知道他的说法可能是什么原因吗?

在一定的性能水平上,您非常关心需要移动磁盘头多少次才能满足查询。要通过连接将两条记录放在一起,您需要至少移动磁盘头两次,除非一条或两条记录完全保存在索引中,并且索引被缓存。(将列添加到索引中,以便满足查询所需的列从索引中出来是一种常见的技术,但索引元组越宽,可以缓存的就越少。)最终,您达到了一个规模,即您想要连接的记录不受同一数据库实例的控制。

连接是一种成本。您仍然可以将数据加入或分组在一起并支付费用,但您会将成本推迟到更便宜的应用层,这样更易于扩展。

所有大型可扩展系统都必须不加入。原因是谷歌使用的BigTable等高度分布式的数据库,其数据非常大,超出了一台机器的范围。连接两个大小为GBs的表是不可伸缩的。事实上,如果您进行大量连接,您将看到大约500万行,您的RDBMS将开始严重依赖索引。在分布式数据库和文档数据库(如mongodb、couchdb等)中,Well索引也要困难得多

未来是以良好的体系结构模型为基础,然后复制数据并在插入更新队列后生成扁平连接表,并随着每组行的更改而更新。MSSQL、Oracle等中的大型RDBMS都达到了需要数据仓库和数据扁平化的程度,以满足报告速度和web等高可扩展需求


当我们获得TB的数据时,连接将成为过去。

我认为这是一个总体概括。包括连接在内的关系数据库概念是现代应用程序程序员可用的一些最有用和最有价值的工具

对于海量数据集,非规范化等概念有其优点。如今,我们倾向于将大型web应用程序开发人员(如Facebook、MySpace等)的话当作福音,而不考虑上下文


一个经过良好优化的连接,包括索引和外键,将是很好的,除非您的行数超过3-4亿行(我不能说更大,因为这是我们开始在我现在工作的最大应用程序上归档的极限)。

我倾向于不同意,因为如果您设计好数据库,您可以获得性能。我们有一个使用Kimball星型模式建模的多TB数据仓库,您必须将事实与维度结合起来,才能进行任何类型的分析和执行(因为它是分区和索引的)。但我必须在一个进程中生成2亿行摘要输出。这种数量的信息根本不会推送给用户

但是,对于典型的面向客户端的web应用程序,它们在每次生成页面时返回的数据量有限,您要加入多少?相反,您的应用程序服务器可以请求行,然后请求相关行,等等。当用C编程的64K小型8086手持设备上没有关系数据库时,我们有一个ISAM库,我们必须在一个表中查找和读取,然后在另一个表中查找和读取。如果你没有处理大量的数据,那么你自己就可以轻松地完成这项工作


但更多的编程和更多的代码意味着更多的bug。这还意味着数据库安全性和约束/关系完整性模型非常薄弱。如果没有加入,您将更多地访问数据库。在最好的情况下,您将从数据库服务器向web服务器返回相同数量的信息。如果web服务器希望根据以前检索到的行筛选行,则情况可能会变得更糟。实际上,web服务器仍在进行连接,但当然,扩展web服务器更容易一些,并且在关系引擎优化方面需要更少的专业知识。

随着扩展,您开始放弃功能,因为它们需要一些成本。子查询优先;然后最终甚至加入。这将使您可以使用表和索引执行任何需要的操作,如Google


SQL数据库通常构建在ISAM上,ISAM只不过是表和索引。所以他只是说他离金属越来越近了。想想看,我猜是MyISAM。这样,您就省去了优化器为您解决问题的麻烦。我肯定会继续下去。但是第一步应该是减少SQL解析器/优化器的开销,并直接操作表和索引。就像以前在foxpro中一样。

当我说它们是邪恶的时候,我有点夸张

对于非常大的数据集,即使它们适合于单个数据库,连接也是一项昂贵的操作(大量非顺序IO)。对于典型的web应用程序负载(90/10读/写),您的读操作需要尽可能便宜,同时您可以在写操作上花费更多的时间(在许多情况下,可以延迟复制写操作)。在典型的高性能web应用程序中,您需要在几百毫秒内执行所有数据库IO,因此这是您的第一个限制。其次,您希望能够执行大量并发请求。这往往意味着能够直接从大型表的索引中收集记录。有人已经提到,你不需要向浏览器发送大量数据,所以不需要在整个数据集上执行连接,但是考虑排序:如果不能直接从索引中获得正确的记录,那么就需要执行完整的记录。