Похоже, что хранение данных в столбце 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)
);