sql >> Database teknologi >  >> RDS >> Mysql

Hamming distance på binære strenge i SQL

Det ser ud til, at lagring af data i en BINÆR kolonne er en tilgang, der er nødt til at fungere dårligt. Den eneste hurtige måde at få anstændig ydeevne på er at opdele indholdet af BINÆR kolonne i flere BIGINT kolonner, der hver indeholder en 8-byte understreng af de originale data.

I mit tilfælde (32 bytes) ville dette betyde brug af 4 BIGINT kolonner og bruge denne 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);

At bruge denne tilgang i min test er over 100 gange hurtigere end at bruge BINÆR tilgang.

FWIW, dette er koden, jeg antydede, mens jeg forklarede problemet. Bedre måder at opnå det samme på er velkomne (jeg kan især ikke lide de binære> hex> decimalkonverteringer):

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)
  );


  1. Find ud af, hvilken partition en given værdi ville være knyttet til i SQL Server (T-SQL)

  2. Sådan udtrækkes ugenummeret fra en dato i PostgreSQL

  3. Gruppekonkat resultater afskåret

  4. Værktøjer til at generere et databasediagram/ER-diagram fra eksisterende Oracle-database?