Comments 10
Странно что не упомянуто основное ограничение хеш-индексов: они могут помогать только в случае простых проверках на равенство.
То есть при поиске x = 500
он поможет, а при поиске x >= 500
уже нет.
И ещё стоит пояснить, что делает скрипт: он создаёт хэш-индексы по всем колонкам всех таблиц схемы public
. Вероятно, это не то, что требуется в реальной жизни.
Вы пишете
"Когда новый ключ добавляется в индекс, PostgreSQL применяет к нему хеш-функцию, которая преобразует ключ в хеш-значение."
Что-то мне намекает, что в индексе сам хеш является ключом. А вы о каком ключе?
"в который помещаются пары "хеш-код — TID" (идентификаторы строк таблицы)."
А затем
"Данные ключа и соответствующий TID сохраняются в соответствующем бакете."
Дак и что ж там сохраняется сам ключ (кстати, что за мифический ключ?) или хеш от него?
"Переполненные страницы используются, когда одна страница бакета не может вместить все записи. Эти страницы имеют такую же структуру, как и основные страницы бакетов, и используются для хранения дополнительных данных."
А с какого момента пара хеш-tid становится дополнительной?
"Эти страницы связаны между собой, что позволяет эффективно управлять большим количеством данных в одном бакете."
Зачем нам больше одного бакета тогда? Вроде всё эффективно.
"какие переполненные страницы в данный момент свободны и могут быть использованы"
Как переполненная может быть свободной? Горячий лёд какой-то.
"Вместо хранения исходного ключа, в бакете хранится его хеш-код вместе с TID."
2:1 в пользу хеш-tid
Не хватает примера с тремя полями.
Не понял зачем хешировать int
Ну а так да, поиск по индексу бывает часто на много быстрей, чем seq scan. Хотя мне известны случаи, когда индекс только повредит производительности. Ну хотя бы очисткой страниц.
Кажется бакеты есть и в кликхаус. Может эти хеши и не нужны вовсе? Ну или какая соль в них, кроме бакетов?
Спасибо. Интересно.
А вот интересно, они уже могут уникальные хеш-индексы или всё ещё нет?
Сравнивать без индекса и с индексом не особо смысл имеет, надо сравнение btree например, дефолтным, что быстрее? Для каких случаев стоит использовать именно хэш, какие ограничения, как например комментарий про равенство. Тема не раскрыта мне кажется)
-- Поиск без индекса
SET enable_seqscan = OFF;
Что-то явно напутали :)
+ по хорошему - надо бы делать все тесты на именно на холодном кэше, ну или грязном. А судя по второму плану - там явно всё уже было в кэше.
+ интересно, что статистика по таблице поменялась :) :)
+ сравнение поиска без индекса и с индексом - ну это такое себе. Лучше уж сравнивать тот-же b-tree и hash. Ну и сразу показать разницу между поиском по уникальным значениям и когда значения часто повторяются
+ мб я уже сильно далеко захожу. Но можно было вкратце объяснить, как работает именно поиск + что делает hash_mem_multiplier
при этом
А вообще, хотелось бы кое-что добавить сюда:
Хэш-индекс не умеет в `index only scan` , поскольку он всегда проверяет строку в в таблице. У b-tree такой проблемы нет из-за карты видимости
Он меньше весит, чем b-tree, но строится в 1 поток ( btree умеет в многопоточку). ЗЫ это инфа старая, мб сейчас умеет, точно не знаю
Хэш-фукнция работает только с операциями равенства ( т.е. column = value ), другие операции ему не доступны. B-tree умеет в поиск по интервалам, поскольку у него всё отсортировано
Не умеет в UNIQUE
Не умеет в INCLUDE
И самое главное - hash-индекс очень помогает, когда вы его правильно употребляете. Ради примера: соединение больших наборов строк по нескольким столбцам сразу. Вы можете увидеть, что планировщик и так решает делать hashJoin, вот вы можете прекрасно базе помочь - просто сделайте по большой таблице хэш-индекс сразу по столбцам, которые участвуют в присоединении
Хеш-Индексы в PostgreSQL