Для каждой версии Postgres, которая поддерживает индексирование хеша , есть предупреждение или примечание, что хеш-индексы «похожи или медленнее» или «не лучше», чем индексы btree , по крайней мере, до версии 8.3. Из документов:
Примечание. Из-за ограниченной полезности хеш-индексов индекс B-дерева обычно предпочтительнее хеш-индекса. У нас нет достаточных доказательств того, что хеш-индексы на самом деле быстрее, чем B-деревья, даже для сравнений. Кроме того, хэш-индексы требуют более грубых блокировок; см. раздел 9.7.
Примечание. Тестирование показало, что хеш-индексы PostgreSQL аналогичны или медленнее, чем индексы B-дерева, а размер и время построения хеш-индексов намного хуже. Хэш-индексы также страдают от низкой производительности при высоком параллелизме. По этим причинам использование хеш-индекса не рекомендуется.
Примечание. Тестирование показало, что хеш-индексы PostgreSQL работают не лучше, чем индексы B-дерева, а размер и время построения хеш-индексов намного хуже. Кроме того, операции с хеш-индексами в настоящее время не регистрируются в WAL, поэтому, возможно, потребуется перестроить хеш-индексы с помощью REINDEX после сбоя базы данных. По этим причинам использование хеш-индекса в настоящее время не рекомендуется.
В этом потоке версии 8.0 они утверждают, что никогда не находили случая, когда хеш-индексы были на самом деле быстрее, чем btree.
Даже в версии 9.2 прирост производительности для чего-либо, кроме написания фактического индекса, был почти ничем, согласно этому сообщению в блоге (14 марта 2016 г.):
хэш-индексы на Postgres от Андре Барбоса.
Мой вопрос, как это возможно?
По определению хеш-индексы - это O(1)
операция, где btree - это O(log n)
операция. Так как же возможно, чтобы O(1)
поиск был медленнее (или даже похож) на поиск правильной ветви и затем нахождение правильной записи?
Я хочу знать, что теория индексирования могла бы когда-либо сделать такую возможность!
источник
Ответы:
Дисковые индексы Btree на самом деле равны O (log N), но это не очень важно для дисковых массивов, которые подходят для этой солнечной системы. Из-за кэширования они в основном O (1) с очень большой константой плюс O ((log N) -1) с небольшой константой. Формально это то же самое, что O (log N), потому что константы не имеют значения в больших обозначениях O. Но они имеют значение в реальности.
Большая часть замедления поиска в хэш-индексе была вызвана необходимостью защиты от повреждения или взаимных блокировок, вызванных изменением размера хэш-таблицы одновременно с поиском. До недавних версий (каждая упомянутая вами версия устарела) эта потребность приводила к еще более высоким константам и довольно слабому параллелизму. Значительно больше человеко-часов ушло на оптимизацию параллелизма BTree, чем на хэш-параллелизм.
источник
Теоретически поиск хеша - это
O(1)
операция, когда хеш ключа отображается непосредственно на физическое местоположение целевой записи. То, как это работает в Postgres, если я правильно понимаю, немного сложнее: хэш ключа отображается в корзину, которая содержит искомый OID. Сегмент может содержать более одной страницы, которую необходимо последовательно сканировать, пока вы не найдете свой конкретный ключ (хеш). Вот почему это выглядит медленнее, чем вы ожидаете.Файл README метода доступа к хэш-индексу в репозитории с исходным кодом содержит все подробности.
источник