我試圖編寫一個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並以這種方式實現它,而不是通過函數創建解決方案,這應該會產生更好的性能。 –