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

MySQL binær mod ikke-binær for hash-id'er

Ja. Ofte gemmes et hash-sammendrag som ASCII-repræsentation af hex-cifre, f.eks. er MD5 af ordet 'hash':

0800fc577294c34e0b28ad2839435945

Dette er en ASCII-streng på 32 tegn.

Men MD5 producerer virkelig en 128-bit binær hashværdi. Dette skal kræver, at kun 16 bytes gemmes som binære værdier i stedet for hex-cifre. Så du kan opnå en vis pladseffektivitet ved at bruge binære strenge.

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

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

Vedr. dine kommentarer om, at du er mere bekymret for ydeevne end pladseffektivitet:

Jeg kender ikke til nogen grund til, at den BINÆRE datatype ville være hurtigere end CHAR.

At være halvt så stor kan være en fordel for ydeevnen, hvis du bruger cachebuffere effektivt. Det vil sige, at en given mængde cachehukommelse kan gemme dobbelt så mange rækker med BINÆRE data, hvis strengen er halvt så stor som den CHAR, der er nødvendig for at gemme den samme værdi i hex. Ligeledes kan cachehukommelsen for indekset på den kolonne lagre dobbelt så meget.

Resultatet er en mere effektiv cache, fordi en tilfældig forespørgsel har større chance for at ramme de cachelagrede data eller indeks i stedet for at kræve en diskadgang. Cache-effektivitet er vigtig for de fleste databaseapplikationer, fordi flaskehalsen normalt er disk I/O. Hvis du kan bruge cachehukommelse til at reducere frekvensen af ​​disk I/O, er det et meget større penge for pengene end valget mellem en eller anden datatype.

Hvad angår forskellen mellem en hash-streng gemt i BINARY versus en BIGINT, ville jeg vælge BIGINT. Cache-effektiviteten vil være endnu større, og også på 64-bit processorer skal heltalsaritmetikken og sammenligninger være meget hurtige.

Jeg har ikke målinger, der understøtter ovenstående påstande. Nettofordelen ved at vælge en datatype frem for en anden afhænger meget af datamønstre og typer af forespørgsler i din database og applikation. For at få det mest præcise svar, skal du prøve begge løsninger og måle forskellen.

Vedr. din formodning om, at binær strengsammenligning er hurtigere end standard-stil-ufølsom streng sammenligning, prøvede jeg følgende 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 strengsammenligning er 17,5 % hurtigere end sammenligning af strenge, der ikke er følsomme over for store og små bogstaver. Men bemærk, at efter at have evalueret dette udtryk 100 millioner gange, er den samlede forskel stadig mindre end 1 sekund. Selvom vi kan måle den relative forskel i hastighed, er den absolutte forskel i hastighed virkelig ubetydelig.

Så jeg vil gentage:

  • Mål, gæt eller formod ikke. Dine uddannede gæt vil være forkerte meget af tiden. Mål før og efter hver ændring, du foretager, så du ved, hvor meget det hjalp.
  • Investér din tid og opmærksomhed, hvor du får mest for pengene.
  • Lad være med at svede de små ting. Selvfølgelig er der en lille forskel med nok gentagelser, men givet disse iterationer er en præstationsforbedring med større absolut fordel stadig at foretrække.


  1. MySQL:Tilføj begrænsning, hvis den ikke eksisterer

  2. Sådan knytter du en MySQL JSON-kolonne til en Java-entitetsejendom ved hjælp af JPA og Hibernate

  3. Problem med MySQL til Visual Studio / Visual Studio 2017 Datasource Wizard. Objektreference er ikke indstillet til en forekomst af et objekt

  4. Generer et sæt eller en sekvens uden sløjfer – del 1