V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
ruandao
V2EX  ›  问与答

uuid 作为主键会存在的问题

  •  
  •   ruandao · 2020-01-15 10:23:19 +08:00 · 3390 次点击
    这是一个创建于 1804 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我在看 高性能 mysql

    然后,里面提到用 uuid 作为主键会出现插入的性能问题,那么是指 uuid4 吗?

    我查看了下 uuid1 好像是时间增序的, 所以应该不会有插入时不是顺序,导致频繁页分裂的问题吧?

    我目前的认知是,uuid1 作为主键的话,因为要进索引,会导致性能问题(因为 uuid1 比较长,每个页能容纳的 key 变少了)

    有什么缺漏,或者不对的地方吗?

    谢谢

    第 1 条附言  ·  2020-01-15 11:41:38 +08:00
    我的第一个疑惑是:

    使用 UUID 来作为聚簇索引则会很糟糕:它使得聚簇索引的插入变得完全随机


    uuid1 会让聚簇索引的插入变得随机吗?
    第 2 条附言  ·  2020-01-15 15:53:59 +08:00
    书上讲的是:

    因为新行的主键值不一定比之前插入的大,所以 InnoDB 无法简单地总是把新行插入到索引的最后,而是需要为新的行寻找合适的位置--通常是已有数据的中间位置--并且分配空间

    。。。
    因为写入是乱序的,InnoDB 不得不频繁地做页分裂操作,以便为新的行分配空间。页分裂会导致移动大量数据,一次插入最少需要修改三个页而不是一个页


    然后 uuid1 是有序的,还存在这个问题吗?
    13 条回复    2020-01-15 16:24:32 +08:00
    ruandao
        1
    ruandao  
    OP
       2020-01-15 10:33:56 +08:00
    主要是书中一句话:

    例如,从性能的角度考虑,使用 UUID 来作为聚簇索引则会很糟糕:它使得聚簇索引的插入变得完全随机,这是最坏的情况,使得数据没有任何聚集特性
    love
        2
    love  
       2020-01-15 10:34:16 +08:00 via Android
    比普通的四字节整数大 4 倍,所以只用在必要的情况下
    binux
        3
    binux  
       2020-01-15 11:03:19 +08:00 via Android
    都 0202 年了,PostgreSQL 它不香吗?
    hbolive
        4
    hbolive  
       2020-01-15 11:23:19 +08:00
    @binux PostgreSQL 香归香,但用什么数据库,往往不是看书的人决定的。。
    ic2y
        5
    ic2y  
       2020-01-15 11:25:44 +08:00
    1. 如果你用的 innodb 引擎,最好用自增值做主键(主键是聚簇索引)。因为 Mysql 的 innodb 引擎使用自增连续的值,可以规避 B+树的频繁分裂和调整。

    2.对于非主键的索引,都是非聚簇索引,每个非聚簇索引的叶子节点存储的是主键的具体值(可以规避插入更新中 B+树的调整)。也就是说:如果主键用 UUID,那么其他的索引都变相的变大了几倍,会导致磁盘空间的浪费。
    okwork
        6
    okwork  
       2020-01-15 11:28:18 +08:00
    打算用 uuid 主键,自然是考虑数据量非常大,后期索引效率比较低。实际情况可以用自增主键,同时加一列索引 uuid,按需使用就可以了
    cmdOptionKana
        7
    cmdOptionKana  
       2020-01-15 11:32:39 +08:00
    现在可以考虑采用 Snowflake
    wx3571
        8
    wx3571  
       2020-01-15 11:36:38 +08:00
    建立非聚簇索引的时候空间要求更大,特别是需要建很多非聚簇索引的时候。索引空间要求变大会造成索引效率变低
    binux
        9
    binux  
       2020-01-15 11:37:28 +08:00 via Android
    @hbolive #4 那让决定用什么数据库的人决定用什么做主键去吧。
    hbolive
        10
    hbolive  
       2020-01-15 12:22:04 +08:00
    @binux 那好,你下午去财务结算下工资,明天不用来了。。
    guokeke
        11
    guokeke  
       2020-01-15 14:46:39 +08:00
    按照我的理解, 如果你按照 char 类型存储的话还是存在上面的问题,你可以尝试按照 binary 类型存 uuid。
    我不一定对,但是 binary 类型是可以优化 uuid 的。
    Foredoomed
        12
    Foredoomed  
       2020-01-15 16:22:12 +08:00
    查询性能可能没什么大区别,但是 uuid 索引占的内存会多很多很多
    ruandao
        13
    ruandao  
    OP
       2020-01-15 16:24:32 +08:00
    @Foredoomed 查询性能应该是有影响的,因为 key 占的空间大,然后一个页能存放的 key 就少,然后就多了几次 IO 操作

    我这边主要的矛盾是书上讲的是 uuid4 吗,因为 uuid1 的序列是有序的
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3813 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 10:27 · PVG 18:27 · LAX 02:27 · JFK 05:27
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.