Ответ
Основное различие заключается в их внутренней структуре и, как следствие, в сценариях использования. B-Tree является универсальным и используется по умолчанию, в то время как Hash-индекс оптимизирован для узкой задачи.
B-Tree (B-дерево)
Сбалансированная древовидная структура, которая хранит данные отсортированными. Это делает её эффективной для широкого спектра операций.
- Лучше всего подходит для:
- Запросов на точное совпадение (
=). - Диапазонных запросов (
>,<,BETWEEN). - Поиска по префиксу (
LIKE 'prefix%'). - Сортировки (
ORDER BY).
- Запросов на точное совпадение (
- Преимущества: Универсальность, поддержка всех типов данных, поддержка ограничений
UNIQUE.
Hash (Хеш-индекс)
Хранит хеш-коды от индексируемых значений. Поиск происходит путем вычисления хеша и прямого доступа к соответствующей "корзине" данных.
- Лучше всего подходит для:
- Только запросов на точное совпадение (
=).
- Только запросов на точное совпадение (
- Ограничения: Не поддерживает диапазонные запросы, сортировку или поиск по префиксу. До версии PostgreSQL 10 хеш-индексы не были транзакционно-безопасными и требовали ручной перестройки.
Пример создания:
-- B-Tree индекс (используется по умолчанию)
CREATE INDEX idx_users_email_btree ON users (email);
-- Hash индекс (нужно явно указать USING HASH)
CREATE INDEX idx_users_email_hash ON users USING HASH (email);
Вывод: На практике B-Tree используется в подавляющем большинстве случаев из-за своей гибкости. Hash может дать небольшое преимущество в производительности и размере для очень больших таблиц, где запросы выполняются исключительно на точное равенство.
Ответ 18+ 🔞
Давай разберем эту индексационную хрень, а то я вижу, у тебя глаза уже стекленеют. Слушай сюда, это же не просто так, это про то, как база данных не ебёт мозги при каждом запросе.
Представь, что у тебя есть список из миллиона пользователей в одной куче, и тебе надо найти Васю Пупкина. Без индекса — это пиздец, полный перебор, как искать иголку в стоге сена, который ещё и горит. А индекс — это такая хитрая шпаргалка, которая говорит: «Вася Пупкин, иди нахуй, он на странице 284, строка 15».
И вот этих шпаргалок бывает два основных вида, и они, блядь, как два разных инструмента: один — швейцарский нож, а второй — кувалда. И сейчас я тебе объясню, когда какую хуйню использовать.
B-Tree (или B-дерево, если по-пацански)
Это наш швейцарский армейский нож, универсальная хуйня, которую Postgres по умолчанию и использует. Устроено оно как сбалансированное дерево, где всё отсортировано по полю, которое ты проиндексировал.
- Когда его пихать куда надо? Да почти всегда, сука! Он заточен под:
- Точный поиск (
WHERE email = 'vasyan@mail.ru'). - Поиск по диапазону, типа «найди всех, кто родился с 1990 по 2000» (
BETWEEN,>,<). - Поиск по началу слова, типа «все имена на "Ва"» (
LIKE 'Ва%'). - Сортировку результатов, чтобы не ждать, пока они там в пизду соберутся (
ORDER BY).
- Точный поиск (
- В чём его сила? Он нихуя не теряет актуальность, работает со всеми типами данных, и на нём можно строить ограничения уникальности.
Hash (Хеш-индекс)
А вот это, дружок, наша кувалда. Очень простая, но тупая в хорошем смысле штука. Берёт значение (например, тот же email), пропускает его через хеш-функцию (получается какая-то цифровая каша), и по этому числу сразу знает, где лежит запись. Прямой доступ, нихуя лишнего.
- Когда им огребать? Только в одной, блядь, ситуации:
- ТОЧНОЕ СОВПАДЕНИЕ (
=). Всё. Точка.
- ТОЧНОЕ СОВПАДЕНИЕ (
- А в чём подвох? А подвох в том, что он нихуя не умеет:
- Искать по диапазону? Не, не слышал.
- Сортировать? Иди нахуй.
- Искать по началу слова? Ты о чём вообще? Раньше (до 10-й версии Postgres) с ними была ещё одна засада — они могли накрыться медным тазом после сбоя, и их надо было перестраивать вручную. Сейчас вроде пофиксили, но осадочек-то остался.
Вот как эту всю хуйню на столбах развесить:
-- B-Tree — дефолтный, можно даже не писать USING BTREE, но для ясности можно
CREATE INDEX idx_users_email_btree ON users USING BTREE (email);
-- Hash — тут надо явно сказать, что мы хотим именно эту кувалду
CREATE INDEX idx_users_email_hash ON users USING HASH (email);
Итог, который тебе в сраку: В 99.9% случаев ты будешь тыкать B-Tree и будешь прав как никогда. Он покрывает все базовые потребности нормального человека. Hash — это такая узкая, ебанутая оптимизация для особых случаев, когда у тебя таблица размером с овердохуища, и ты с неё только и делаешь, что ищешь по точному совпадению. Во всех остальных случаях — это стрельба из пушки по воробушкам, только место на диске жрёт.