Information
- Rating
- Does not participate
- Location
- Москва, Москва и Московская обл., Россия
- Works in
- Date of birth
- Registered
- Activity
Specialization
Бэкенд разработчик, Разработчик баз данных
Старший
Git
SQL
PostgreSQL
Docker
Linux
Python
ООП
Базы данных
Английский язык
C++
Я когда впервые увидел проблему с долгим временем планирования при вычислении селективности в джойнах, я тоже пробовал кэшировать детостанные данные на время двойного цикла в eqseljoin. Но применение хэш-поиска сокращает время сильнее. Поэтому на хэш-поиске и остановился. Быть может реально в 'референсном форке' лучше будет.
Скидываю код с хэш-поиском
Нет, сейчас мы не кэшируем статистику. После перехода на хэш-поиск для сопоставления MCV время планирования заметно сократилось. Фактически основная проблема была решена сменой алгоритма, поэтому мы пока не видим дальнейшие оптимизации целесообразными.
На момент написания статьи и в версии 17.6 мы действительно использовали сортировку перед сравнением. Однако сейчас реализован подход, описанный по второй ссылке : мы строим хэш-таблицу по MCV-статистике одного столбца и затем ищем совпадения по значениям MCV другого столбца. После этого изменения сопоставление MCV больше не опирается на вложенные циклы с большим количеством повторных вызовов
byteaeq(), и в профилировании его вклад в CPU больше не выделяется.По умолчанию
default_statistics_target = 100. Он определяет максимальное количество элементов в MCV-списке для столбца, если не задано явно черезALTER TABLE ... ALTER COLUMN ... SET STATISTICS.Алгоритм обхода MCV меняется, когда сумма размеров MCV-списков двух соединяемых столбцов становится больше или равна 200. То есть патч сработает, если оба столбца в условии
JOINимеют MCV-списки максимального размера, то есть 100 элементов каждый.https://commitfest.postgresql.org/patch/5929/
По оптимизации "Ускорение планирования запросов при высоких значениях default_statistics_target" на текущий момент идет обсуждение смены алгоритма обхода MCV
(https://commitfest.postgresql.org/patch/5929/)