我试图编写一个MySQL存储函数来生成v4 UUID,如RFC 4122第4.4节(http://www.ietf.org/rfc/rfc4122.txt)中所述。一些调整后,我最初的天真的努力如下:如何加快我的MySQL UUID v4存储功能?
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
上述功能是相当缓慢:比内置UUID()
慢近100倍,根据MySQL的BENCHMARK()
功能。使用MySQL的C API编写UDF的缺点是,我可以做些什么改进,例如从运行时削减一个数量级?
如果有一个已经存在的,广受好评的UUID UDF或存储过程,我也很乐意听到这个消息。
我不知道答案,但你怎么想创建自己的函数,而不是使用已经提到的MySQL的UUID()(我不知道MySQL的是否与RFC 4122不同,所以如果它确实感到抱歉问)? –
根据RFC4122,MySQL的'UUID()'不会生成uuid,并且其生成方式会打破基于语句的复制。 –
你的函数也会打破基于语句的复制。您可以通过将binlog格式设置为“MIXED”或“ROW”来避免这种情况,以便日志的重播不会调用该函数,而是插入使UUID()可供使用的实际行值。另外,有什么保证你的函数不会生成重复的UUID?你得到的唯一的随机因素是5个RAND()的调用(这首先使它变慢)。我会为MySQL编写一个UDF并以这种方式实现它,而不是通过函数创建解决方案,这应该会产生更好的性能。 –