在 UUID 主键字段上拥有索引和唯一约束有什么好处?看来,如果我有 25M 记录并且必须插入新记录,则必须搜索所有 25M 记录并检查它们是否具有相同的 UUID(带或不带索引)。查找该记录也很麻烦,因为 uuid 无法排序。我错过了什么吗?
是的。
UUID 值可以排序。它们可能不是按照您认为特别理想的顺序排序的。但 UUID 是数据值。它们可以进行比较(它们是否相等、是否小于另一个),因此可以对它们进行排序。
声明 aPRIMARY KEY有效地创建了一个 UNIQUE 索引。对于某些存储引擎(例如InnoDB),主键是表的簇键。对于其他存储引擎(例如MyISAM),表存储为堆,并且PRIMARY KEY本质上与声明NOT NULL约束并添加UNIQUE INDEX相同。
是的,当向表中插入一行时,存储引擎必须确保不违反 PRIMARY KEY 或 UNIQUE KEY 约束...正在插入的新行上的值不会重复已存储的值。
这(理论上)相当于检查所有 25M 行。但由于有可用的索引结构,存储引擎不需要检查所有单独的行。它使用索引来代替。
由于索引是“按顺序”存储的,因此存在大量包含不需要检查的行的块。不需要检查它们,因为具有键列的特定值的行不可能存储在这些块中。存储引擎非常有效地识别存在或可能存在具有“重复”键值的行的块。
跟进
上面的答案主要指的是MySQL(问题中的标签之一)。就 PostgreSQL 而言,我相信这些观点是有效的。
就使用 UUID 值作为表的主键而言,与其他一些选择相比,可能会存在一些性能缺陷。两个主要问题:存储 UUID 所需的空间,以及 UUID 值不是按顺序生成/插入的。
一个UUID是128位,也就是16个字节。但它通常会转换为 36 个字符的“人类可读形式 (?)”。将 UUID 存储为 36 个字符比简单整数占用更多空间。当 CHAR(36) 用作主键时,它不仅存储在主键索引中,而且还作为“行指针”存储在所有辅助索引中。这意味着每个块的键更少,这反过来又意味着索引中的块更多。
另一个问题是,新值不仅插入到索引的后面,而且插入到整个索引中,导致块分裂和碎片。我们不必过度担心所有这些,因为数据库会为我们处理它。但使用 UUID 作为主键可能会导致明显的“性能降低”(与使用升序整数值相比),至少在测试实验室中是这样。
就添加以 PRIMARY KEY 作为前导列的二级索引“有什么好处”而言。一般来说,没有什么好处。
(我不会排除拥有这样的索引可能有益的极端情况。我希望这些极端情况涉及索引组织表中非常长的行,以及一些可以有效利用二级索引。但这种性能优势会带来一定的代价:额外的块(内存和磁盘 I/O)以及维护二级索引的额外工作。)
| 归档时间: |
|
| 查看次数: |
3610 次 |
| 最近记录: |