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


104

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

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

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


9
Таблицы хеширования не поддерживают запросы диапазона и не могут плавно увеличиваться или уменьшаться во время работы.
— hmakholm ушел над Моникой

3
@HenningMakholm Почему не использовать хеш для столбцов, для которых не нужны запросы диапазона?
— Pacerier 05

Ответы:


117

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

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

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

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

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

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

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

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

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


Не могли бы вы подробнее рассказать о восстановлении индекса? Означает ли это, что в течение x дней, пока индекс перестраивается, таблица в этот период полностью недоступна для использования?
— Pacerier 05

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

«Вы можете получить доступ к элементам только по их первичному ключу» - вы имеете в виду значение столбца, имеющего право на индекс, будь то первичный ключ или другой тип индекса?
— Марк Фишер

90

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

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


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 был основан на хешировании и хорошо работал. Имея в наши дни больше памяти для поддержки эффективных разреженных хэш-таблиц и избыточное хеширование для поддержки запросов с ограниченным диапазоном, я бы сказал, что хеширование все же может иметь свое место (некоторые предпочли бы другие формы сопоставления сходства без диапазона, такие как подстановочные знаки и регулярные выражения ). Мы также рекомендуем копировать, чтобы цепочки столкновений оставались непрерывными, когда иерархии памяти имеют большие различия в скорости.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.