Il semble que le stockage des données dans un BINARY
colonne est une approche vouée à des performances médiocres. Le seul moyen rapide d'obtenir des performances décentes est de diviser le contenu du BINARY
colonne dans plusieurs BIGINT
colonnes, chacune contenant une sous-chaîne de 8 octets des données d'origine.
Dans mon cas (32 octets), cela signifierait utiliser 4 BIGINT
colonnes et en utilisant cette fonction :
CREATE FUNCTION HAMMINGDISTANCE(
A0 BIGINT, A1 BIGINT, A2 BIGINT, A3 BIGINT,
B0 BIGINT, B1 BIGINT, B2 BIGINT, B3 BIGINT
)
RETURNS INT DETERMINISTIC
RETURN
BIT_COUNT(A0 ^ B0) +
BIT_COUNT(A1 ^ B1) +
BIT_COUNT(A2 ^ B2) +
BIT_COUNT(A3 ^ B3);
L'utilisation de cette approche, dans mes tests, est plus de 100 fois plus rapide que l'utilisation du BINARY
approche.
FWIW, c'est le code auquel je faisais allusion en expliquant le problème. De meilleures façons d'accomplir la même chose sont les bienvenues (je n'aime particulièrement pas les conversions binaire> hexadécimal> décimal) :
CREATE FUNCTION HAMMINGDISTANCE(A BINARY(32), B BINARY(32))
RETURNS INT DETERMINISTIC
RETURN
BIT_COUNT(
CONV(HEX(SUBSTRING(A, 1, 8)), 16, 10) ^
CONV(HEX(SUBSTRING(B, 1, 8)), 16, 10)
) +
BIT_COUNT(
CONV(HEX(SUBSTRING(A, 9, 8)), 16, 10) ^
CONV(HEX(SUBSTRING(B, 9, 8)), 16, 10)
) +
BIT_COUNT(
CONV(HEX(SUBSTRING(A, 17, 8)), 16, 10) ^
CONV(HEX(SUBSTRING(B, 17, 8)), 16, 10)
) +
BIT_COUNT(
CONV(HEX(SUBSTRING(A, 25, 8)), 16, 10) ^
CONV(HEX(SUBSTRING(B, 25, 8)), 16, 10)
);