Ответ
Hash-индексы оптимальны только для операций точного совпадения (=), но имеют серьёзные ограничения:
Ограничения Hash-индексов:
-
Не поддерживают диапазонные запросы
-- Hash-индекс НЕ поможет SELECT * FROM orders WHERE total_amount > 1000; SELECT * FROM users WHERE created_at BETWEEN '2023-01-01' AND '2023-12-31'; -
Не поддерживают сортировку (ORDER BY)
-- Неэффективно с Hash-индексом SELECT * FROM products ORDER BY price DESC; -
Не поддерживают поиск по префиксу
-- Hash-индекс бесполезен SELECT * FROM articles WHERE title LIKE 'PHP%'; -
Только операции равенства — Hash-индекс вычисляет хэш-значение, поэтому
WHERE id = 5работает быстро, ноWHERE id > 5— нет.
Практический пример из PostgreSQL:
-- Создаём Hash-индекс для точного поиска по email
CREATE INDEX idx_users_email_hash ON users USING hash(email);
-- Эффективный запрос
SELECT * FROM users WHERE email = 'alice@example.com';
-- Для этих запросов нужен B-tree индекс
CREATE INDEX idx_users_created_btree ON users(created_at);
SELECT * FROM users WHERE created_at > '2024-01-01' ORDER BY created_at;
Когда использовать Hash-индекс:
- Таблицы поиска (lookup tables) с уникальными значениями
- Частые запросы с
=без сортировки - Когда данные часто обновляются (в некоторых СУБД Hash эффективнее для вставок)
В MySQL InnoDB Hash-индексы используются автоматически для адаптивного хэширования, но явно создать Hash-индекс нельзя.
Ответ 18+ 🔞
А, слушай, про эти hash-индексы расскажу, а то народ часто нихуя не понимает, где их пихать. Представь себе, будто у тебя есть супербыстрый справочник, но только для одного вопроса: «А где тут Вася?». И всё. Больше нихуя.
В чём их подвох, ёпта:
-
Про диапазоны забудь как страшный сон
-- С этим hash-индекс накроется медным тазом сразу SELECT * FROM orders WHERE total_amount > 1000; SELECT * FROM users WHERE created_at BETWEEN '2023-01-01' AND '2023-12-31';Ему похуй на «больше» или «между». Он тупо хэш считает и ищет полное совпадение. Всё остальное — пиздец и полный перебор.
-
Сортировку (ORDER BY) не потянет
-- Запрос будет тормозить, как мартышка на льду SELECT * FROM products ORDER BY price DESC;Потому что данные в нём разбросаны, как говно по тайге — никакой логической последовательности. Для сортировки нужен другой урод.
-
Поиск «начинается с...» — не его история
-- Hash-индекс тут просто пизда рулю SELECT * FROM articles WHERE title LIKE 'PHP%';Он же не строки сравнивает, а хэши. «PHP%» и «PHQ%» — для него это вообще разные вселенные, ядрёна вошь.
-
Равенство — его единственная фишка Вот где он охуенно быстр:
WHERE id = 5. Вычислил хэш от пятёрки — бац, и сразу адрес записи. А попросиWHERE id > 5— и он просто охуеет и пойдёт читать всю таблицу.
Пример из реальности, на PostgreSQL:
-- Делаем hash-индекс для почты, если ищем только по полному совпадению
CREATE INDEX idx_users_email_hash ON users USING hash(email);
-- Запрос летает, как угорелый
SELECT * FROM users WHERE email = 'alice@example.com';
-- А для вот этого нужен уже B-tree, иначе будет пиздец
CREATE INDEX idx_users_created_btree ON users(created_at);
SELECT * FROM users WHERE created_at > '2024-01-01' ORDER BY created_at;
Так когда же его впендюрить?
- Для всяких справочников, где ключ уникальный и ищется только по
=. - Когда тебе похуй на сортировки и диапазоны — только точный поиск.
- Иногда для часто обновляемых данных (зависит от СУБД, там свои заморочки).
Кстати, в MySQL InnoDB ты явно hash-индекс не создашь — там эта штука внутри работает как адаптивное хэширование, само решает, где его применить. Так что не пытайся, чувак, это бесполезно.