B-дерево против хеш-таблицы

104

В MySQL тип индекса - это b-дерево, и доступ к элементу в b-дереве осуществляется за логарифмическое амортизированное время O(log(n)).

С другой стороны, доступ к элементу в хеш-таблице находится в O(1).

Почему не используется хеш-таблица вместо b-дерева для доступа к данным внутри базы данных?

JohnJohnGa
источник
9
Таблицы хеширования не поддерживают запросы диапазона и не могут плавно увеличиваться или уменьшаться во время работы.
hmakholm ушел над Моникой
3
@HenningMakholm Почему не использовать хеш для столбцов, для которых не нужны запросы диапазона?
Pacerier 05

Ответы:

117

Вы можете получить доступ к элементам только по их первичному ключу в хеш-таблице. Это быстрее, чем с древовидным алгоритмом ( O(1)вместоlog(n) ), но вы не можете выбирать диапазоны ( все, что находится между xиy ). Алгоритмы дерева поддерживают это, Log(n)тогда как хеш-индексы могут привести к полному сканированию таблицы O(n). Кроме того, постоянные накладные расходы на хеш-индексы обычно больше ( что не является фактором в тета-нотации, но все же существует ). Кроме того, древовидные алгоритмы обычно легче поддерживать, увеличивать вместе с данными, масштабировать и т. Д.

Индексы хеширования работают с заранее определенными размерами хешей, так что в итоге вы получаете несколько «корзин», в которых хранятся объекты. Эти объекты снова зацикливаются, чтобы действительно найти нужный внутри этого раздела.

Таким образом, если у вас маленькие размеры, у вас много накладных расходов на мелкие элементы, большие размеры приводят к дальнейшему сканированию.

Современные алгоритмы хэш-таблиц обычно масштабируются, но масштабирование может быть неэффективным.

Действительно, существуют масштабируемые алгоритмы хеширования. Не спрашивайте меня, как это работает - для меня это тоже загадка. AFAIK они эволюционировали из масштабируемой репликации, где повторное хеширование не так просто.

Его называют РАШ - R eplication U NDER S calable Н озоления, и эти алгоритмы, таким образом , называют алгоритмы Раша.

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

Компромисс для древовидных алгоритмов невелик, и они подходят почти для каждого случая использования и поэтому используются по умолчанию.

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

Surrican
источник
Не могли бы вы подробнее рассказать о восстановлении индекса? Означает ли это, что в течение x дней, пока индекс перестраивается, таблица в этот период полностью недоступна для использования?
Pacerier 05
это зависит от используемой системы баз данных. вопрос касался только теоретических аспектов. Я действительно не знаю деталей реализации общих систем баз данных. но обычно этого не должно быть, потому что второй индекс может быть построен, пока первый все еще используется
Surrican
«Вы можете получить доступ к элементам только по их первичному ключу» - вы имеете в виду значение столбца, имеющего право на индекс, будь то первичный ключ или другой тип индекса?
Марк Фишер
90

На самом деле, похоже, что MySQL использует оба типа индексов: либо хеш-таблицу, либо b-дерево согласно следующей ссылке .

Разница между использованием b-дерева и хеш-таблицы заключается в том, что первая позволяет использовать сравнения столбцов в выражениях, использующих операторы =,>,> =, <, <= или BETWEEN, а последняя используется только для сравнения на равенство , в которых используются операторы = или <=>.

lmiguelvargasf
источник
9
Это нечестно. Лучший ответ имеет самый низкий балл.
Андрей Беньковский 04
6
Это именно то, что я искал. Меня больше волновало, как это влияет на мои запросы, чем технический анализ.
Бен Дехган
Ага! Этот ответ мне помог больше всего.
Рон Росс
Большое спасибо, прошло много времени, но этот ответ мне тоже очень помог.
Рехам Фахми
14

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

Эмиль Викстрём
источник
2
Можно ли перепрограммировать, пока база данных подключена? Или нам нужно заблокировать таблицу, чтобы все перешить?
Pacerier 05
1
Pacerier, MySQL не поддерживают хеш-индексы. Теоретически возможно перефразировать индекс, пока база данных все еще находится в сети (продолжайте использовать старый индекс, создайте новый индекс, переключитесь на новый, когда это будет сделано), но я не знаю, что MySQL будет делать, если они будут хеш-индикаторы.
Emil Vikström
3
MySQL поддерживает хеш-индексы, верно? : dev.mysql.com/doc/refman/5.5/en/index-btree-hash.html
Pacerier 05
Кажется, ты прав. Для меня это было новостью! Я должен стараться идти в ногу с развитием :-) Тогда вам гораздо лучше ответить на ваш вопрос, чем мне, но, как я уже сказал: теоретически это возможно.
Emil Vikström
Кстати, почему вы говорите, что «btree можно легко выгружать на диск, а хеш-таблицу - нет»? Нельзя ли сохранить хеш-таблицу на диске, поскольку достаточно простого поиска ключа?
Pacerier
6

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

Джонатан Уэзерхед
источник
0

Выбор DB / OS был основан на хешировании и хорошо работал. Имея в наши дни больше памяти для поддержки эффективных разреженных хэш-таблиц и избыточное хеширование для поддержки запросов с ограниченным диапазоном, я бы сказал, что хеширование все же может иметь свое место (некоторые предпочли бы другие формы сопоставления сходства без диапазона, такие как подстановочные знаки и регулярные выражения ). Мы также рекомендуем копировать, чтобы цепочки столкновений оставались непрерывными, когда иерархии памяти имеют большие различия в скорости.

РОНАЛЬД ЛУИ
источник