Warum ist meine eigene MySQL-Funktion so viel langsamer als inlining gleich in der Abfrage?

Ich benutz diese SELECT Abfrage zu Lesen unsigned Ganzzahlen, die IPv4-Adressen zusammen und stellen diese als lesbare dotted-quad-strings.

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;

Meiner test-Daten, diese Abfrage dauert 3,6 Sekunden zu führen.

Dachte ich, dass erstellen Sie eine benutzerdefinierte gespeicherte Funktion für die int->string Umwandlung würde es ermöglichen, einfacher zu Lesen, Abfragen und ermöglichen die Wiederverwendung, so dass ich dies:

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)
  );

Mit dieser Funktion meine Abfrage sieht wie folgt aus:

SELECT IntToIp(ip) FROM ips;

aber mit meiner test-Daten, das dauert 13.6 Sekunden zu führen.

Ich würde erwarten, dass diese langsamer bei der ersten Ausführung, da es eine zusätzliche Dereferenzierungsebene beteiligt, aber fast 4-mal langsamer scheint übertrieben. Ist so viel Langsamkeit erwartet?

Bin ich mit aus der box MySQL-server-5.1 auf Ubuntu 10.10 mit keine änderungen in der Konfiguration.


Reproduzieren meinem test, erstellen Sie eine Tabelle und füllen Sie mit 1,221,201 Zeilen:

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();
InformationsquelleAutor Day | 2011-08-12
Schreibe einen Kommentar