Postgres UUID包含索引和约束

时间:2016-04-04 22:18:22

标签: mysql postgresql

在作为UUID的主键字段上建立索引和唯一约束有什么好处?似乎如果我有25M记录并且我必须插入新记录,则必须搜索所有25M记录并检查它们是否具有相同或不具有索引的UUID。找到该记录也很麻烦,因为uuid无法排序。我错过了什么吗?

1 个答案:

答案 0 :(得分:2)

  1. 可以对UUID值进行排序。它们可能不会按您认为特别理想的顺序排序。但是UUID是数据值。它们可以进行比较(它们是相等的,比另一个更小),因此可以对它们进行分类。

  2. 声明PRIMARY KEY有效地创建了一个UNIQUE索引。对于一些存储引擎(例如InnoDB),PRIMARY KEY是表的簇密钥。对于其他存储引擎(例如MyISAM),表存储为堆,PRIMARY KEY与声明NOT NULL约束和添加UNIQUE INDEX基本相同。

  3. 是的,在向表中插入行时,存储引擎必须确保没有违反PRIMARY KEY或UNIQUE KEY约束...正在插入的新行上的值不会复制已经存在的值存储

  4. 这相当于(理论上)对所有25M行的检查。但由于存在可用的索引结构,因此存储引擎无需检查所有单独的行。它改为使用索引。

    因为索引是“按顺序”存储的,所以有大量的块包含不需要检查的行。它们不需要被检查,因为具有键列的特定值的行不可能存储在那些块中。存储引擎非常有效地识别存在或存在具有“重复”键值的行的一个块。

    <强>后续

    上面的答案主要是指MySQL(问题中的一个标签)。就PostgreSQL而言,我相信这些要点是有效的。

    就使用UUID值作为表的PRIMARY KEY而言,与其他一些选择相比,可能存在一些性能缺陷。两个主要问题:存储UUID所需的空间,并且不会按顺序生成/插入UUID值。

    UUID是128位,即16字节。但这经常转换为36个字符的“人类可读形式(?)”。将UUID存储为36个字符比简单整数占用更多空间。当CHAR(36)用作PRIMARY KEY时,它不会仅存储在主键索引中,而是存储为所有二级索引中的“行指针”。这意味着每个块的密钥更少,这反过来意味着索引中的块更多。

    另一个问题是,新值不仅插入索引的后面,而是插入索引中,导致块拆分和碎片。我们不必过分担心这一切,因为数据库会为我们处理它。但是,使用UUID作为PRIMARY KEY可以转化为可测量的“较慢的性能”(与使用递增的整数值相比),至少在测试实验室中是这样。

    在以PRIMARY KEY作为前导列添加二级索引的“有什么好处”方面。一般来说,没有任何好处。

    (我不打算排除有这样一个索引可能有用的极端情况。我希望那些极端情况在索引组织表中涉及很长的行,以及一些可能使得特定的SQL语句有效使用二级索引。但这种性能优势需要付出代价,额外的块(内存和磁盘i / o)以及维护二级索引的额外工作。)