Хорошее замечание: pg_test_timing действительно не предназначен для оценки производительности доступа. Однако в одном из обсуждений мэилинг листа PostgreSQL нашёл инфо, что если задержки велики, значит, сам процесс измерения времени в системе нестабилен или медленный - косвенный признак, что случайный доступ (который требует многократных обращений к диску) будет страдать от больших задержек. Согласен, не лучший из возможных способов тестирования, однако другие утилиты требуют более глубокого погружения, а по-хорошему и вовсе отдельной статьи. Добавил уточнения в статью
В идеале было бы добавить планы запросов + пояснения к ним. Но это ухудшило бы читабельность, т.к. планы различаются в основном ключевыми словами, вроде конкретного типа join. Выбрал альтернативу - контекстные ссылки на эти самые ключевые слова
Да, действительно, один из операторов нельзя отключить полностью
enable_hashjoin - Enables or disables the query planner's use of hash-join plan types. The default is on.
enable_mergejoin - Enables or disables the query planner's use of merge-join plan types. The default is on.
enable_nestloop - Enables or disables the query planner's use of nested-loop join plans. It is impossible to suppress nested-loop joins entirely, but turning this variable off discourages the planner from using one if there are other methods available. The default is on.
Хеш-индекс – это структура данных на диске, которая позволяет быстро находить отдельные значения (=).
Hash Join – это алгоритм, который массово сопоставляет строки между двумя таблицами, создавая временный хеш в памяти.
Поскольку Hash Join должен обработать все строки соединяемой таблицы, хеш-индекс ему не помогает – он предназначен только для точечного поиска (WHERE column = value)
Hash Join в PostgreSQL всегда строит свою временную хеш-таблицу, даже если на соединяемом поле есть хеш-индекс.
Проблема хеш-индекса в том, что каждый поиск требует отдельного обращения к индексу на диске(!). Если в ordersмиллионы строк, то поиск каждого user_id через хеш-индекс будет слишком дорогим.
Hash Join эффективен, потому что он загружает данные в память(!) один раз и использует их для всех сравнений, а не выполняет отдельные обращения к индексу.
В случае с autowired-конструктором первый и второй этапы "сливаются"
Код в конце статьи
Хорошее замечание:
pg_test_timing
действительно не предназначен для оценки производительности доступа.Однако в одном из обсуждений мэилинг листа PostgreSQL нашёл инфо, что если задержки велики, значит, сам процесс измерения времени в системе нестабилен или медленный - косвенный признак, что случайный доступ (который требует многократных обращений к диску) будет страдать от больших задержек.
Согласен, не лучший из возможных способов тестирования, однако другие утилиты требуют более глубокого погружения, а по-хорошему и вовсе отдельной статьи.
Добавил уточнения в статью
В целом, согласен
Обновлю статью
В идеале было бы добавить планы запросов + пояснения к ним.
Но это ухудшило бы читабельность, т.к. планы различаются в основном ключевыми словами, вроде конкретного типа
join
.Выбрал альтернативу - контекстные ссылки на эти самые ключевые слова
Да, действительно, один из операторов нельзя отключить полностью
Исправил статью, спасибо за наблюдение
Hash Join и хеш-индексы решают разные задачи:
Хеш-индекс – это структура данных на диске, которая позволяет быстро находить отдельные значения (=).
Hash Join – это алгоритм, который массово сопоставляет строки между двумя таблицами, создавая временный хеш в памяти.
Поскольку Hash Join должен обработать все строки соединяемой таблицы, хеш-индекс ему не помогает – он предназначен только для точечного поиска (
WHERE column = value
)Да, действительно, начиная с версии 10 количество бакетов увеличивается динамически.
Исправил статью, спасибо за наблюдение
Hash Join в PostgreSQL всегда строит свою временную хеш-таблицу, даже если на соединяемом поле есть хеш-индекс.
Проблема хеш-индекса в том, что каждый поиск требует отдельного обращения к индексу на диске(!). Если в
orders
миллионы строк, то поиск каждогоuser_id
через хеш-индекс будет слишком дорогим.Hash Join эффективен, потому что он загружает данные в память(!) один раз и использует их для всех сравнений, а не выполняет отдельные обращения к индексу.