Parece que almacenar los datos en un BINARY
columna es un enfoque destinado a funcionar mal. La única forma rápida de obtener un rendimiento decente es dividir el contenido de BINARY
columna en múltiples BIGINT
columnas, cada una de las cuales contiene una subcadena de 8 bytes de los datos originales.
En mi caso (32 bytes) esto significaría usar 4 BIGINT
columnas y usando esta función:
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);
Usar este enfoque, en mis pruebas, es más de 100 veces más rápido que usar BINARY
acercamiento.
FWIW, este es el código que estaba insinuando al explicar el problema. Son bienvenidas mejores formas de lograr lo mismo (especialmente no me gustan las conversiones binarias> hexadecimales> decimales):
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)
);