индекса Hash для InnoDB


0

Я видел схему базы данных, которая выглядела как этот

CREATE TABLE foo (
    name_hash bigint, 
    name varachar(500), 
    a varchar(500), 
    b varchar(500), 
    ... 
    PRIMARY KEY (name_hash), 
    KEY ... 
); 

Это, кажется, попытка ограничить размер индекса, используя 8-байтовое целое, а не строка 100 байт. При поиске значения по имени приложение хеширует его, а затем использует этот хэш в SQL-запросе вместо имени.

Это довольно утомительно, и я не уверен, что это необходимо.


Есть ли особенность MySQL InnoDB, который делает что-то подобное - что ищет строку его гораздо короче хэш, чтобы соответствовать индексу в памяти?

Или он уже делает что-то подобное?

  0

Как вы собираетесь обрабатывать хеш-конфликты, если хеш используется в качестве первичного ключа? 03 июн. 152015-06-03 23:12:35

  0

@akuzminsky, в этом случае они потерпят неудачу. Для 10 миллионов записей существует вероятность 0,0003% двух записей, имеющих один и тот же 8-байтовый хеш. Я полагаю, что это может быть не уникальный ключ. 03 июн. 152015-06-03 23:20:58

  0

ОК. хеш в качестве первичного ключа сделает страницы с нелистовыми страницами более плотными, а дерево - более мелким. Но листовые страницы (с остальными полями) по-прежнему будут поступать в память. 03 июн. 152015-06-03 23:24:29

1

У InnoDB нет инструмента, который бы ничего не делал, как описано.

InnoDB имеет предел 767 байт за столбец в индексе. Это имеет место для VARCHAR(255) utf8 или VARCHAR(191) utf8mb4. Кроме того, InnoDB хочет поместить длинный VARCHARs в другой блок, если вся запись больше, чем около 8 КБ. Будет ли это распространено? (Не слепо используйте VARCHAR(500), если вы можете обоснованно определить более низкий предел.)

План A: Сжатие (в клиенте) name и храните его в VARBINARY(255). Предполагая, что это типичный текст, сжатие будет около 3: 1. Используйте это вместо Hash.

План B: Разделите имя на 2 или 3 столбца, чтобы соблюдался предел индекса. (Уродливое решение!)

План C: Измените предел 767. (Возможно, но я забыл детали на данный момент.)

Что-то примечание: любой приличный «хэш» очень случайный. То есть каждая новая строка попадает в какое-то случайное место в таблице. Когда таблица превысит innodb_buffer_pool_size, вы будете делать все больше и больше операций ввода-вывода, тем самым замедляя работу.

Как будет выглядеть SELECTs? Будете ли вы иметь другие индексы в этой таблице? Будете ли вы JOIN на name_hash? Все это может повлиять на «лучший» способ разработки схемы.

  0

План D: обновить до 5.7, что повышает лимит. 12 янв. 172017-01-12 16:29:37