Det verkar som att lagra data i en BINARY kolumn är ett tillvägagångssätt som måste prestera dåligt. Det enda snabba sättet att få anständig prestanda är att dela upp innehållet i BINARY kolumn i flera BIGINT kolumner, som var och en innehåller en 8-byte delsträng av originaldata.
I mitt fall (32 byte) skulle detta innebära att man använder 4 BIGINT kolumner och använda denna funktion:
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);
Att använda detta tillvägagångssätt, i mina tester, är över 100 gånger snabbare än att använda BINARY tillvägagångssätt.
FWIW, det här är koden jag antydde när jag förklarade problemet. Bättre sätt att åstadkomma samma sak är välkomna (jag gillar särskilt inte de binära> hex> decimalkonverteringarna):
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)
);