Бинарный MySQL против недвоичного для хэш-идентификаторов - PullRequest
26 голосов
/ 02 февраля 2009

Предполагая, что я хочу использовать хеш в качестве идентификатора вместо числового. Будет ли преимущество в производительности хранить их как BINARY по сравнению с недвоичным?

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

Ответы [ 2 ]

29 голосов
/ 02 февраля 2009

Да. Часто дайджест хеша сохраняется в виде ASCII-представления шестнадцатеричных цифр, например, MD5 слова 'хеш':

0800fc577294c34e0b28ad2839435945

Это 32-символьная строка ASCII.

Но MD5 действительно выдает 128-битное двоичное хеш-значение. Это должно требовать, чтобы только 16 байтов хранились как двоичные значения вместо шестнадцатеричных цифр. Таким образом, вы можете получить некоторую эффективность использования пространства, используя двоичные строки.

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

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

Re. Ваши комментарии о том, что вас больше беспокоит производительность, чем эффективность использования пространства:

Я не знаю ни одной причины, по которой тип данных BINARY был бы быстрее, чем CHAR.

Быть вдвое меньше может быть преимуществом для производительности, если вы эффективно используете буферы кеша. То есть данный объем кеш-памяти может хранить вдвое больше строк данных BINARY, если строка равна половине размера CHAR, необходимого для хранения того же значения в шестнадцатеричном формате. Аналогично, кэш-память для индекса в этом столбце может хранить в два раза больше.

В результате получается более эффективный кэш, поскольку случайный запрос имеет большую вероятность попадания в кэшированные данные или индекс, а не требует доступа к диску. Эффективность кэширования важна для большинства приложений баз данных, поскольку обычно узким местом является дисковый ввод-вывод. Если вы можете использовать кэш-память для уменьшения частоты дискового ввода-вывода, это намного больший удар, чем выбор между одним типом данных или другим.

Что касается разницы между хеш-строкой, хранящейся в BINARY, и BIGINT, я бы выбрал BIGINT. Эффективность кэша будет еще выше, а также на 64-битных процессорах целочисленная арифметика и сравнения должны быть очень быстрыми.

У меня нет измерений, подтверждающих вышеуказанные требования. Чистая выгода от выбора одного типа данных перед другим во многом зависит от шаблонов данных и типов запросов в вашей базе данных и приложении. Чтобы получить наиболее точный ответ, вы должны попробовать оба решения и измерить разницу.


Re. Ваше предположение, что сравнение двоичных строк выполняется быстрее, чем сравнение строк без учета регистра по умолчанию, я попробовал следующий тест:

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)

Таким образом, сравнение двоичных строк происходит на 17,5% быстрее, чем сравнение строк без учета регистра. Но обратите внимание, что после вычисления этого выражения 100 миллионов раз, общая разница все равно будет меньше 1 секунды. Хотя мы можем измерить относительную разницу в скорости, абсолютная разница в скорости действительно незначительна.

Итак, я повторюсь:

  • Измерьте, не угадывайте и не предполагайте. Ваши образованные догадки будут ошибаться в большинстве случаев. Измеряйте до и после каждого внесенного вами изменения, чтобы вы знали, насколько это помогло.
  • Инвестируйте свое время и внимание, чтобы получить максимальную отдачу от доллара.
  • Не парься по мелочам. Конечно, небольшая разница складывается с достаточным количеством итераций, но, учитывая эти итерации, повышение производительности с большей абсолютной выгодой все еще предпочтительнее.
6 голосов
/ 02 февраля 2009

С инструкция :

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. 

Поскольку CHAR (32) BINARY вызывает создание столбца BINARY (32) под капотом, преимущество заключается в том, что для сортировки по этому столбцу потребуется меньше времени и, возможно, меньше времени для поиска соответствующих строк, если столбец проиндексированы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...