17

在通过 SO 进行搜索时,我发现了两个相互矛盾的答案(甚至还有一个评论),但没有明确的答案:

问题是:如果将 TEXT/BLOB 字段存储在表之外,是否有任何性能优势?

我们猜测:

  • 您选择正确(如果需要,仅选择 TEXT/BLOB,不选择 *)
  • 表在有意义的地方被正确索引(所以这不是“如果你索引它”的问题)
  • 数据库设计并不重要。这是一个在这种特殊情况下识别 MySQL 行为的问题,而不是解决某些数据库设计问题。假设这个数据库只有一个表(或两个,如果 TEXT/BLOB 被分开)
  • 使用的引擎:innoDB(其他引擎也会很有趣,如果他们获取不同的结果)

这篇文章指出,将 TEXT/BLOB 放入单独的表中,只有在您已经以错误的方式进行 SELECT 时才会有所帮助(即使没有必要也总是选择 TEXT/BLOB) -基本上说明,TEXT/BLOB 在同一张表基本上是更好的解决方案(复杂性更低,不会影响性能等),因为 TEXT/BLOB 无论如何都是单独存储的

将 TEXT 列移动到另一个表中唯一会带来任何好处的情况是,如果它倾向于通常从表中选择所有列。这只是引入了第二种不良做法来弥补第一种不良做法。不言而喻,二错不等于三左。

带有 TEXT 列的 MySQL 表


然而,这篇文章指出:

当表有 TEXT 或 BLOB 列时,该表不能存储在内存中

这是否意味着在表中包含 TEXT/BLOB 已经足以影响性能?

MySQL varchar(2000)与文本?


我的问题基本上是:正确答案是什么?

如果SELECT正确的话,是否将 TEXT/BLOB 存储到单独的表中真的很重要吗?

或者甚至在表中包含 TEXT/BLOB 是否会产生潜在的性能影响?

4

2 回答 2

17

更新:自 5.7 版以来,梭子鱼是默认的 InnoDB 文件格式。

如果在您的 MySQL 版本上可用,请使用 InnoDB Barracuda 文件格式

innodb_file_format=barracuda

ROW_FORMAT=Dynamic在您的 MySQL 配置中并使用(或)设置您的表Compressed以实际使用它。

这将使 InnoDB 在行页面之外存储 BLOB、TEXT 和更大的 VARCHAR,从而使其效率更高。有关更多信息,请参阅此 MySQLperformanceblog.com 博客文章

据我了解,出于性能原因,使用梭子鱼格式将使将 TEXT/BLOB/VARCHAR 存储在单独的表中不再有效。但是,我认为记住适当的数据库规范化总是好的。

于 2012-12-17T15:49:11.027 回答
6

一个性能提升是拥有一个具有固定长度记录的表。这意味着没有可变长度字段,如 varchar 或 text/blob。对于固定长度的记录,MySQL 不需要“寻找”记录的结尾,因为它知道大小偏移量。它还知道加载 X 条记录需要多少内存。具有固定长度记录的表不太容易出现碎片,因为从已删除记录中获得的可用空间可以完全重用。MyISAM 表实际上从固定长度记录中获得了一些其他好处。

假设您使用的是 innodb_file_per_table,将 tex/blob 保存在单独的表中将增加使用文件系统缓存的可能性,因为该表会更小。

也就是说,这是一个微优化。您还可以做很多其他事情来获得更大的性能提升。例如,使用 SSD 驱动器。当您的表变得如此之大以至于您必须实施分片时,它不会给您带来足够的性能提升来推迟计算的日子。

您不再听说使用“原始文件系统”的数据库,尽管它可以更快。“原始”是指数据库直接访问磁盘硬件,绕过任何文件系统。我认为甲骨文仍然支持这一点。但这不值得增加复杂性,您必须真正知道自己在做什么。在我看来,将您的文本/blob 存储在单独的表中并不值得为可能的性能提升而增加复杂性。你真的需要知道你在做什么,以及你的访问模式,才能利用它。

于 2012-12-23T22:35:03.867 回答