Изглежда, че съхраняването на данните в BINARY
колона е подход, който неизбежно се представя лошо. Единственият бърз начин да получите прилична производителност е да разделите съдържанието на BINARY
колона в множество BIGINT
колони, всяка от които съдържа 8-байтов подниз от оригиналните данни.
В моя случай (32 байта) това би означавало използване на 4 BIGINT
колони и с помощта на тази функция:
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);
Използването на този подход в моето тестване е над 100 пъти по-бързо от използването на BINARY
подход.
FWIW, това е кодът, за който намекнах, докато обяснявах проблема. По-добри начини за постигане на същото нещо са добре дошли (особено не харесвам двоични> шестнадесетични> десетични преобразувания):
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)
);