Pull to refresh
227
0.1
Егор Рогов @erogov

Пользователь

Send message

Рад, что книга понравилась!

В оригинале:

A high value of work_mem is specified globally (at instance level). Users often underestimate the multiplying effect for such blanket decisions.

А у вас совершенно некорректная отсебятина:

Ограничения глобальной переменной work_mem. Например, если у вас 32Гб RAM и work_mem=1Гб, то больше 32 соединений вы никогда не запустите. Каждое соединение PostgreSQL будет выделять этот размер памяти.

Нехорошо так делать, перевод должен быть переводом.

Только что записанные данные обязательно попадают не только в журнал, но и в основную базу. Только не сразу на диск, а сначала в буферный кеш. Вот из буферного кеша они и читаются.

А вот если сервер упадет, тогда недошедшие до диска данные будут восстановлены из журнала.

Да, вы правильно понимаете, с оговоркой на подраздел «Частые и редкие лексемы» - они могут обрабатываться по-разному.

Но специально для этого случае есть класс операторов jsonb_path_ops, и я только сейчас понял, что ничего про него не написал. Он складывает в индекс не отдельные ключи и значения, а целиком путь от корня JSON до значения.

Вот место в документации, где про это написано.

Ух, какая раритетная у вас книжка по Постгресу! Свежая версия всегда лежит здесь: postgrespro.ru/education/books/introbook

Всегда приятно, когда работа оказывается нужной!

Серия про индексы уже порядком устарела, но в грядущей книге будет свежая информация.

Правильно, ли я понимаю, что количество версий строк зависит, от интенсивности обновления строки и настроек автовакуума?

Да.

И если это так, то при одной версии строки (вставили строку и после не было обновлений и удаления этой строки) речь о корреляции вообще не должна идти, потому что не с чем коррелировать, т.е. нет версий строк?

Нет. Видимо я запутал вас тем, что написал корреляция версий строк (с порядком в индексе), а не просто корреляция строк. Даже если у каждой строки ровно одна версия, то самих-то строк обычно много.

Вот пусть в таблице хранятся числа, для каждой строки есть только одна (актуальная) версия, и в страницах эти версии расположены так:

0 1 2 3 4 5 6 7 8 9.

Тогда корреляция равна единице, поскольку в индексе эти числа упорядочены точно так же.

А если в страницах что-то такое вперемешку:

3 8 2 6 9 4 1 0 7 5,

то корреляция около нуля.

Все это не важно, если мы читаем по индексу ровно одну строку, но очень важно, если читаем много.

Процитирую сам себя (абзацем ниже):

Дело в том, что чем ниже корреляция, тем выше вероятность того, что следующая версия табличной строки, идентификатор которой выдает метод доступа, окажется на другой странице. Поэтому вместо последовательного чтения узел Index Scan «скачет» со страницы на страницу, а количество обращений к страницам в предельном случае может достигать количества выбираемых версий строк.

Если в странице помещается M строк, а запросу надо прочитать N строк, то при идеальной корреляции нужно прочитать всего N/M страниц, а при нулевой корреляции - N страниц. Вот и разница.

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

Спасибо, рад, что читаете!

Спасибо, рад, что понравилось.

Критерий простой - итоговая стоимость всего запроса.

Одна из идей, которые я пытался донести - что при расчете стоимости планировщик учитывает кучу разных факторов и в итоге выбирает наименее затратный с его точки зрения план. Поэтому в каком-то смысле лучший вариант оптимизации - дать планировщику всю необходимую информацию и не мешать. (Что, конечно, не всегда работает.)

Если же пытаться оптимизировать запрос самому (лишая планировщик свободы выбора и подсказывая ему ходы), то обычно держат в уме набор правил. Типа того, что первой должна идти таблица с наиболее ограничивающим условием, или что одни и те же данные не надо читать дважды. Для коротких OLTP-подобных запросов характерен точечный доступ по индексу и соединение вложенными циклами, для длинных OLAP-подобных запросов - полные сканирования (и часто секционирование) и хеш-соединения. В этой книге все довольно хорошо и подробно написано.

Рад, что читаете!

EXPLAIN позволяет узнать правду о конкретном запросе. Если смотреть в целом по системе, то есть масса статистических представлений. Ну и pg_stat_statements тоже, разумеется. Посмотрите еще схему Алексея Лесовского (Query Planning, Query Execution).

Важная часть картины - ожидания. Чтобы смотреть за ними, нужно расширение pg_wait_sampling или что-то аналогичное. В QPT мы это рассматриваем в теме "Профилирование".

Ну и можно что-то вывести в журнал сообщений, если это удобно. Те же временные файлы.

Сокращение времени выполнения запросов за счёт того, что часть действий происходит при подготовке. Чем чаще запрос повторяется в одном сеансе, и чем запрос короче, тем сильнее эффект.

А если выбирает мало данных, то параллельное выполнение вообще не будет использоваться. Сейчас перечитал - у меня неточность: параллельное сканирование не рассматривается, если мы собираемся прочитать из таблицы меньше, чем min_parallel_table_scan_size (а не если полный размер таблицы меньше этого значения).

В целом-то вы правы, но реализация parallel seq scan вряд ли даст такой выигрыш. Другое дело - сканирование секционированных таблиц начиная с версии 11: https://commitfest.postgresql.org/16/987/ Вот там параллельно читаются целые секции и никакая синхронизация в процессе чтения не нужна.

Честно говоря, не думаю. Процессам все время приходится синхронизироваться между собой, так что особого параллелизма при чтении не получится. Да и в модели стоимости считается, что чтение будет последовательным.

Ой. Это был неаккуратный копипаст, поправил. Хорошо, что вы обратили внимание, спасибо!

Что-то я пропустил в свое время ваш вопрос, прошу прощения.

В такой ситуации, как вы описываете, лучше сделать индекс только по some_array и не смущать планировщик.

А если вы создадите индекс по двум столбцам, то одно из двух. Либо планировщик сообразит, что проще найти несколько документов по some_array, а потом перепроверить user_id без индекса (как описано в разделе «Частые и редкие лексемы»), либо не сообразит - тогда, конечно, будет плоховато. Но это надо проверять на конкретных данных.

На здоровье, рад, что статьи пригождаются.

В узле GIN (как и в B-дереве) лексемы упорядочены. В том узле, о котором речь, у нас три лексемы: «залома», «нек» и «стоя». Поскольку «залома» < «кудряв» <= «нек», то идти надо в «нек».

Алексей, вроде все верно. Во втором предложении «меньше пяти» относится не длине списка, а к значению параметра. А длина там ровно 5, столько узлов в примере.

Но согласен, написал я не очень. Подумаю, как это переформулировать почетче.

Information

Rating
2,960-th
Location
Москва, Москва и Московская обл., Россия
Works in
Date of birth
Registered
Activity