如何加快我的MySQL UUID v4存储功能?

时间:2011-07-08 11:41:13

标签: mysql stored-procedures uuid

我正在尝试编写一个MySQL存储函数来生成v4 UUID,如RFC 4122的4.4节(http://www.ietf.org/rfc/rfc4122.txt)中所述。经过一些调整后,我最初的天真努力如下:

CREATE FUNCTION UUID_V4()
RETURNS BINARY(16)
READS SQL DATA
BEGIN
    SET @uuid = CONCAT(
        LPAD( HEX( FLOOR( RAND() * 4294967296 ) ), 8, '0' ),
        LPAD( HEX( FLOOR( RAND() * 4294967296 ) ), 8, '0' ),
        LPAD( HEX( FLOOR( RAND() * 4294967296 ) ), 8, '0' ),
        LPAD( HEX( FLOOR( RAND() * 4294967296 ) ), 8, '0' )
    );
    SET @uuid = CONCAT(
        SUBSTR( @uuid FROM 1 FOR 12 ),
        '4',
        SUBSTR( @uuid FROM 14 FOR 3 ),
        SUBSTR( 'ab89' FROM FLOOR( 1 + RAND() * 4 ) FOR 1 ),
        SUBSTR( @uuid FROM 18 )
    );
    RETURN UNHEX(@uuid);
END

根据MySQL的UUID()功能,上述功能非常慢:几乎比内置BENCHMARK()慢100倍。如果没有使用MySQL的C API编写UDF,我可以在这里进行任何改进,比如说,从运行时中减去一个数量级的数量级吗?

如果已经存在,备受推崇的UUID UDF或存储过程,我也很高兴听到这个消息。

1 个答案:

答案 0 :(得分:9)

我没有测试这是正确性还是性能。这只是一个而不是两个连接的想法。

create function uuid_v4()
returns binary(16)
begin
    set @h1 = lpad(hex(floor(rand() * 4294967296)), 8, '0');
    set @h2 = lpad(hex(floor(rand() * 4294967296)), 8, '0');
    set @h3 = lpad(hex(floor(rand() * 4294967296)), 8, '0');
    set @h4 = lpad(hex(floor(rand() * 4294967296)), 8, '0');

    set @uuid = concat(
        @h1,
        substr(@h2 from 1 for 4),
        '4',
        substr(@h2 from 6),
        substr('ab89' from floor(1 + rand() * 4) for 1 ),
        substr(@h3 from 2),
        @h4
    );
    return unhex(@uuid);
end
;

另外,为什么在你的函数中使用READS SQL DATA