sql >> Databáze >  >> RDS >> Mysql

Hammingova vzdálenost na binárních řetězcích v SQL

Zdá se, že ukládání dat do BINARY sloupec je přístup, který bude mít špatný výkon. Jediný rychlý způsob, jak dosáhnout slušného výkonu, je rozdělit obsah BINARY sloupec ve více BIGINT sloupce, z nichž každý obsahuje 8bajtový podřetězec původních dat.

V mém případě (32 bajtů) by to znamenalo použití 4 BIGINT sloupce a pomocí této funkce:

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

Použití tohoto přístupu je při mém testování více než 100krát rychlejší než použití BINARY přístup.

FWIW, toto je kód, na který jsem narážel při vysvětlování problému. Vítáme lepší způsoby, jak dosáhnout stejné věci (obzvláště nemám rád binární> hex> desítkové převody):

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. Existují nějaké nevýhody vždy používat nvarchar (MAX)?

  2. Data s otevřeným zdrojovým kódem rostou:Vyberte si MySQL, NoSQL nebo obojí

  3. Jak nainstalovat phpMyAdmin

  4. Entity Framework nefunguje s časovou tabulkou