V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
ruandao
V2EX  ›  问与答

uuid 作为主键会存在的问题

  •  
  •   ruandao · Jan 15, 2020 · 4090 views
    This topic created in 2308 days ago, the information mentioned may be changed or developed.

    我在看 高性能 mysql

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

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

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

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

    谢谢

    Supplement 1  ·  Jan 15, 2020
    我的第一个疑惑是:

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


    uuid1 会让聚簇索引的插入变得随机吗?
    Supplement 2  ·  Jan 15, 2020
    书上讲的是:

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

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


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

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

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

    我这边主要的矛盾是书上讲的是 uuid4 吗,因为 uuid1 的序列是有序的
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   5942 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 69ms · UTC 06:04 · PVG 14:04 · LAX 23:04 · JFK 02:04
    ♥ Do have faith in what you're doing.