【发布时间】:2020-10-01 14:47:31
【问题描述】:
我有一个包含数百万行的 MariaDB InnoDB 表,但其中包含仅由数字和时间戳组成的短的、固定宽度的行。 我们通常使用任何现有的列来搜索、过滤和排序行。
我们想添加一列来为每一行存储一个关联的“url”。理想情况下,每一行都有它的 url。 我们知道我们不会通过 url 列进行排序、搜索和过滤。 我们不介意将 URL 截断为前 255 个字节,因此我们将为其指定 VARCHAR 类型。 但是,该列的宽度当然是可变的。整条记录会变成可变宽度,很多情况下原始记录的宽度会加倍。
我们正在考虑使用不同的辅助表来存储 varchar。 我们可以在查询数据时加入它们,或者更有效地——可能——只获取我们正在显示的页面的 url。
这种方法是否可取? 是否有更好的替代方案也可以让我们保持性能?
更新:正如用户 Bill Karwin 在下面的一条评论中指出的那样,InnoDB 不像 MyISAM 那样从固定宽度中受益,所以这里真正的问题是关于行的大小,而不是关于固定宽度与可变宽度讨论。
【问题讨论】:
-
使用辅助表很好 - 无论单个表是否真的存在“性能影响”。几百万仍然是零钱——使用性能测试和指标来确定额外的关注/努力是否合理。什么是“关键”选项?那些自然(哈哈)适合建立一对一的关系。
-
@user2864740 数百万个场景的问题在于它经常与其他也有数百万行的表连接。我不确定我明白你所说的“关键”选项是什么意思,但我为辅助表考虑的 PK 只是第一个表的 PK 的副本。这将是 PK 和 FK(我想非自动增量是允许作为 PK 的,对吧?)。
-
InnoDB 不关心固定宽度与可变宽度的行。 MyISAM 中固定宽度的行有一些优势,但 InnoDB 没有。
-
归结为连接上使用的索引。虽然可能会有一些额外的磁盘利用率(“每个特定查询的数据存储效率较低”),但查询的性能复杂性决定了它可以减少多少读取。在大多数情况下,未经过滤的百万 x 百万叉积会非常糟糕 - 行大小主要影响“C”常数。可能值得探索using covering indices 而不是手动分离。
-
在某些极端情况下,分离一些体积庞大且很少使用的列是有好处的。但是您必须拥有一个规模非常大或流量非常高的数据库,然后才值得额外的复杂性。它与固定宽度与可变宽度无关。
标签: mysql mariadb denormalization