uuid 作为主键会存在的问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
ruandao
V2EX    问与答

uuid 作为主键会存在的问题

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

    我在看 高性能 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     Solana     985 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 27ms UTC 23:05 PVG 07:05 LAX 16:05 JFK 19:05
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86