sql >> Databasteknik >  >> RDS >> Mysql

MySQL binärt mot icke-binärt för hash-ID:n

Ja. Ofta lagras ett hashsammandrag som ASCII-representation av hexadecimala siffror, till exempel är MD5 för ordet "hash":

0800fc577294c34e0b28ad2839435945

Det här är en ASCII-sträng med 32 tecken.

Men MD5 producerar verkligen ett 128-bitars binärt hashvärde. Detta bör kräver att endast 16 byte lagras som binära värden istället för hexadecimala siffror. Så du kan få lite utrymmeseffektivitet genom att använda binära strängar.

CREATE TABLE test.foobar (
  id BINARY(16) NOT NULL PRIMARY KEY
);

INSERT INTO test.foobar (id) VALUES (UNHEX(MD5('hash')));

Re. dina kommentarer om att du är mer bekymrad över prestanda än utrymmeseffektivitet:

Jag känner inte till någon anledning till att den BINÄRA datatypen skulle vara snabbare än CHAR.

Att vara hälften så stor kan vara en fördel för prestandan om man använder cachebuffertar effektivt. Det vill säga, en given mängd cacheminne kan lagra dubbelt så många rader värda BINÄR data om strängen är hälften så stor som CHAR som behövs för att lagra samma värde i hex. På samma sätt kan cacheminnet för indexet på den kolumnen lagra dubbelt så mycket.

Resultatet är en mer effektiv cache, eftersom en slumpmässig fråga har en större chans att träffa cachad data eller index, istället för att kräva en diskåtkomst. Cacheeffektivitet är viktigt för de flesta databasapplikationer, eftersom flaskhalsen vanligtvis är disk I/O. Om du kan använda cacheminne för att minska frekvensen av disk I/O, är det mycket större pengar för pengarna än valet mellan en datatyp eller en annan.

När det gäller skillnaden mellan en hashsträng lagrad i BINARY kontra en BIGINT, skulle jag välja BIGINT. Cacheeffektiviteten kommer att bli ännu högre, och även på 64-bitarsprocessorer bör heltalsaritmetiken och jämförelser vara mycket snabba.

Jag har inga mått som stödjer påståendena ovan. Nettofördelen med att välja en datatyp framför en annan beror mycket på datamönster och typer av frågor i din databas och applikation. För att få det mest exakta svaret måste du prova båda lösningarna och mäta skillnaden.

Re. ditt antagande att binär strängjämförelse är snabbare än standard skiftlägesokänslig strängjämförelse, försökte jag följande test:

mysql> SELECT BENCHMARK(100000000, 'foo' = 'FOO');
1 row in set (5.13 sec)

mysql> SELECT BENCHMARK(100000000, 'foo' = BINARY 'FOO');
1 row in set (4.23 sec)

Så binär strängjämförelse är 17,5 % snabbare än skiftlägesokänslig strängjämförelse. Men lägg märke till att efter att ha utvärderat detta uttryck 100 miljoner gånger är den totala skillnaden fortfarande mindre än 1 sekund. Även om vi kan mäta den relativa skillnaden i hastighet, är den absoluta skillnaden i hastighet verkligen obetydlig.

Så jag upprepar:

  • Mät, gissa eller anta inte. Dina välutbildade gissningar kommer att vara fel många gånger. Mät före och efter varje förändring du gör, så att du vet hur mycket det hjälpte.
  • Investera din tid och uppmärksamhet där du får störst valuta för pengarna.
  • Svetta inte de små sakerna. Naturligtvis ger en liten skillnad tillräckligt många iterationer, men med tanke på dessa iterationer är en prestandaförbättring med större absolut nytta fortfarande att föredra.


  1. Två kolumner i underfrågan i where-satsen

  2. Bas 36 till Base 10 konvertering med endast SQL

  3. Infoga variabler MySQL med Python, fungerar inte

  4. Åtgärda "FEL: saknar FROM-klausulpost för tabell" i PostgreSQL när du använder UNION, EXCEPT eller INTERSECT