我们有一个“笔记”表,即使我们没有搜索笔记内容,一些查询也会变得非常慢。我们想知道将笔记内容移动到单独的表格中是否会加快速度?
我认为分离内容并不重要——TEXT 字段本质上不只是指向磁盘上其他位置的指针吗?还是桌子大小很重要?
InnoDB 能更好地处理这个问题吗?
我们有一个“笔记”表,即使我们没有搜索笔记内容,一些查询也会变得非常慢。我们想知道将笔记内容移动到单独的表格中是否会加快速度?
我认为分离内容并不重要——TEXT 字段本质上不只是指向磁盘上其他位置的指针吗?还是桌子大小很重要?
InnoDB 能更好地处理这个问题吗?
在 MyISAM 中,记录存储在块中。有大约 20 种不同的块类型,其中一些可能非常大。这些用于 BLOB/TEXT 值。我从未见过 MyISAM 记录存储指向 BLOB 的指针(但我不会坚持)。
在 InnoDB 中,BLOB/TEXT 值也是记录的一部分,并存储在页面中,只要总记录大小不超过 ~7k。否则 768 个第一个字节存储在页中,其余部分存储在外部页中。(在梭子鱼格式中,它只存储一个指向外部页面的 20 字节指针)。
TEXT 字段具有 MySQL 文档(压缩 BLOB、VARCHAR 和 TEXT 列)所称的“列外存储”
该链接包含有关使用压缩的更多信息。Percona 也是如此。
我有一些关于 InnoDB Storage 的帖子,与 PostgreSQL 的做法相比
Aug 26, 2014
:提案:MySQL blob 处理修订May 01, 2012
:什么比longblob大?Mar 21, 2012
:在 mysql InnoDB 中有很多 NULL 列有害吗?在 MyISAM 方面,你必须使用
ROW_FORMAT=COMPRESSED
来提高存储使用率MyISAM only——通常一条记录是
.MYD
文件中连续的字节流。这包括TEXT
和BLOB
列。索引具有指向 .MYD 文件的字节偏移量(或记录号)。行后
DELETEd
,.MYD 中可能有孔。MyISAM 更喜欢在附加到 .MYD 之前填充漏洞。然而,孔可能不够大。在这种情况下,记录的一部分存储在第一个孔中,并且链接(字节偏移量)存储到记录的下一部分。只要有必要,这种链接就会持续下去。因此,如果表中有很多“流失”(删除+插入等),那么新的
INSERTs
存储可能会非常低效。也就是说,它们可能是支离破碎的和分散的。OPTIMIZE TABLE
这是对 MyISAM 表有用的少数情况之一。将OPTIMIZE
通过有效地读取每一行并将其重写为新的 (tmp) .tmd 来重建表,稍后将重命名为 .MYD。这会对行进行碎片整理并消除任何剩余的间隙。.MYD 没有“块”结构。相比之下,.MYI 保存所有索引,包括
PRIMARY KEY
1KB BTree 块中的 .数据的唯一缓存是操作系统提供的。这往往是 4GB 块,与表中行的记录边界的相关性为零。
什么时候有并行表——问题真的是关于这个。(但我需要先说上述内容。)
很难明确指出何时手动按列拆分表是有用的。
案例 1:您在表格中进行了大量搜索,但没有触及 TEXT 字段。在其他地方拥有大的 TEXT 字段可以避免踩到那些大奶牛稻田。
JOIN
获取一行的 TEXT 并不那么昂贵。案例 2:你总是
LIKE
在 TEXT 字段上做。然后垂直分区会减慢速度。我在几个项目中完成了案例 1。
案例 1 可以通过这个技巧进一步增强:
笔记:
LIMIT
或GROUP BY
,或...);另一个技巧是压缩文本字段(并将其放入 BLOB)。
(这两个“技巧”可以应用于 InnoDB。)