Wygląda na to, że przechowywanie danych w pliku BINARY
kolumna jest podejściem, które ma słabe wyniki. Jedynym szybkim sposobem na uzyskanie przyzwoitej wydajności jest podzielenie zawartości pliku BINARY
kolumna w wielu BIGINT
kolumny, z których każda zawiera 8-bajtowy podciąg oryginalnych danych.
W moim przypadku (32 bajty) oznaczałoby to użycie 4 BIGINT
kolumn i za pomocą tej funkcji:
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);
Korzystanie z tego podejścia w moich testach jest ponad 100 razy szybsze niż użycie BINARY
podejście.
FWIW, to jest kod, do którego sugerowałem, wyjaśniając problem. Lepsze sposoby osiągnięcia tego samego są mile widziane (szczególnie nie lubię konwersji binarnych> szesnastkowych> dziesiętnych):
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)
);