【发布时间】:2011-10-25 10:45:01
【问题描述】:
我反复使用这个SELECT 查询来读取代表 IPv4 地址的无符号整数,并将它们呈现为人类可读的点状四进制字符串。
SELECT CONCAT_WS('.',
FLOOR(ip/POW(256,3)),
MOD(FLOOR(ip/POW(256,2)), 256),
MOD(FLOOR(ip/256), 256),
MOD(ip, 256))
FROM ips;
使用我的测试数据,执行此查询需要 3.6 秒。
我认为 creating a custom stored function 用于 int->string 转换可以更容易阅读查询并允许重用,所以我做了这个:
CREATE FUNCTION IntToIp(value INT UNSIGNED)
RETURNS char(15)
DETERMINISTIC
RETURN CONCAT_WS(
'.',
FLOOR(value/POW(256,3)),
MOD(FLOOR(value/POW(256,2)), 256),
MOD(FLOOR(value/256), 256),
MOD(value, 256)
);
使用这个函数,我的查询看起来像这样:
SELECT IntToIp(ip) FROM ips;
但根据我的测试数据,这需要 13.6 秒来执行。
我希望这在第一次运行时会变慢,因为涉及到额外的间接级别,但慢了近 4 倍似乎过分了。 预计会有这么慢吗?
我在 Ubuntu 10.10 上使用开箱即用的 MySQL 服务器 5.1,没有进行任何配置更改。
要重现我的测试,请创建一个表并填充 1,221,201 行:
CREATE TABLE ips (ip INT UNSIGNED NOT NULL);
DELIMITER //
CREATE PROCEDURE AddIps ()
BEGIN
DECLARE i INT UNSIGNED DEFAULT POW(2,32)-1;
WHILE (i>0) DO
INSERT INTO ips (ip) VALUES (i);
SET i = IF(i<3517,0,i-3517);
END WHILE;
END//
DELIMITER ;
CALL AddIps();
【问题讨论】:
标签: mysql performance user-defined-functions