2009-02-02 7 views
25

En supposant que je veux utiliser un hachage comme un ID au lieu d'un numérique. Serait-ce un avantage de performance de les stocker comme BINARY sur non-binaire?MySQL binaire contre non-binaire pour les ID de hachage

CREATE TABLE `test`.`foobar` (
    `id` CHAR(32) BINARY CHARACTER SET ascii COLLATE ascii_bin NOT NULL, 
    PRIMARY KEY (`id`) 
) 
CHARACTER SET ascii; 
+0

Pouvez-vous être plus précis sur ce que « avantage » que vous cherchez? Essayez-vous d'optimiser pour l'espace, pour la performance, pour la facilité d'utilisation, ou pour une gamme de valeurs uniques? –

+0

Je m'intéresse principalement aux avantages de performance car l'espace est presque libre et une valeur de 128 bits est le double de la plage de valeurs que j'aurais à utiliser une clé primaire BIGINT. – Gumbo

Répondre

28

Oui. Souvent, un hachage condensé est stocké sous forme de la représentation ASCII des chiffres hexadécimaux, par exemple MD5 du mot « hachage » est:

0800fc577294c34e0b28ad2839435945 

Ceci est une chaîne ASCII de 32 caractères.

Mais MD5 produit réellement une valeur de hachage binaire de 128 bits. Ce devrait nécessitent seulement 16 octets pour être stockés en tant que valeurs binaires au lieu de chiffres hexadécimaux. Vous pouvez donc gagner en espace en utilisant des chaînes binaires.

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

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

Re. vos commentaires que vous êtes plus préoccupé par la performance que l'efficacité de l'espace:

Je ne connais aucune raison que le type de données BINARY serait plus rapide que CHAR.

Être moitié moins grand peut être un avantage pour les performances si vous utilisez efficacement les tampons de mémoire cache. C'est-à-dire qu'une quantité donnée de mémoire cache peut stocker deux fois plus de lignes de données BINARY si la chaîne a la moitié de la taille de CHAR requise pour stocker la même valeur en hexadécimal. De même, la mémoire cache de l'index sur cette colonne peut stocker deux fois plus.

Le résultat est un cache plus efficace, car une requête aléatoire a plus de chance de toucher les données ou l'index mis en cache, au lieu de nécessiter un accès au disque. L'efficacité du cache est importante pour la plupart des applications de base de données, car le goulot d'étranglement est généralement l'E/S disque. Si vous pouvez utiliser la mémoire cache pour réduire la fréquence des E/S de disque, c'est un avantage beaucoup plus grand que le choix entre un type de données ou un autre. En ce qui concerne la différence entre une chaîne de hachage stockée dans BINARY et une BIGINT, je choisirais BIGINT. L'efficacité du cache sera encore plus grande, et aussi sur l'arithmétique des processeurs 64 bits et les comparaisons devraient être très rapides.

Je n'ai pas de mesures à l'appui des revendications ci-dessus. L'avantage net de choisir un type de données plutôt qu'un autre dépend beaucoup des modèles de données et des types de requêtes dans votre base de données et votre application. Pour obtenir la réponse la plus précise, vous devez essayer les deux solutions et mesurer la différence.


Re. votre supposition que la comparaison de chaîne binaire est plus rapide que par défaut comparaison de chaînes insensibles à la casse, j'ai essayé le test suivant:

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) 

comparaison de chaînes est donc binaire 17,5% plus rapide que la comparaison de chaînes insensibles à la casse. Mais remarquez qu'après avoir évalué cette expression 100 millions de fois, la différence totale est toujours inférieure à 1 seconde.Alors que nous pouvons mesurer la différence relative de vitesse, la différence absolue de vitesse est vraiment insignifiante.

Je vais répéter:

  • Mesure, ne pas deviner ou supposer. Vos suppositions instruites se tromperont la plupart du temps. Mesurez avant et après chaque changement que vous faites, de sorte que vous sachiez combien cela a aidé.
  • investir votre temps et d'attention où vous obtenez le plus pour votre argent.
  • Ne pas transpirer les petites choses. Bien sûr, une minuscule différence s'additionne avec suffisamment d'itérations, mais étant donné ces itérations, une amélioration des performances avec un plus grand bénéfice absolu est toujours préférable.
+0

J'ai déjà pensé à ça. Cela me sauverait la moitié de l'espace bien que 2^128 soit assez bas (BIGINT a juste 2^64 et c'est déjà assez). – Gumbo

+0

J'ai mis à jour ma question comme vous l'avez demandé. Je serais bien si vous y jetez un autre coup d'oeil. – Gumbo

+0

Je pensais que le binaire serait plus rapide car il n'y a pas d'autres comparaisons de lettres majuscules et minuscules, comme comparaison normale font que « « foo »= « FOO » » est vrai, mais « BINARY « foo »= 'FOO" » false . – Gumbo

6

De the manual:

The BINARY and VARBINARY types are similar to CHAR and VARCHAR, except 
that they contain binary strings rather than non-binary strings. That is, 
they contain byte strings rather than character strings. This means that 
they have no character set, and sorting and comparison are based on the 
numeric values of the bytes in the values. 

Depuis CHAR (32) BINARY une colonne BINARY (32) à créer sous le capot, l'avantage est que cela prendra moins de temps pour trier par cette colonne, et probablement moins de temps pour trouver les lignes correspondantes si la colonne est indexée.

+0

Merci pour votre réponse. Vous n'arriveriez pas à connaître quelques chiffres à ce sujet? – Gumbo

Questions connexes