Как стать автором
Обновить
215
0.1
Егор Рогов @erogov

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

Отправить сообщение

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

Дело в том, что чем ниже корреляция, тем выше вероятность того, что следующая версия табличной строки, идентификатор которой выдает метод доступа, окажется на другой странице. Поэтому вместо последовательного чтения узел 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, столько узлов в примере.

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

Рад, что вдохновляетесь!

Насчет архитектуры. В документации, к сожалению, нет внятного короткого описания. Мы пытались что-то изобразить в DBA1 в темах 4-10. Попробуйте еще посмотреть Вову Бородина (видео https://www.youtube.com/watch?v=ejLzS6rVpkk, слайды https://www.slideshare.net/yandex/postgre-sql-41754731).

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

Сертификация будет по версии 13, чтобы соответствовать курсам. (Да, сначала мы думали про 12-ю, но поезд уже ушел.)

Совершенно верно! Спасибо, я поправлю картинку.

А вы помните, что было в 90-х? Из города все разъехались на заработки, как раз где-то в 1995-м прекратилось строительство УНК, на этом наука и завершилась. Что график и иллюстрирует.

Ограничением возраста, это, увы, не исправить.

Думаю, потому, что дополнительная сложность перевешивает потенциальную пользу. Уникальность поддерживается только B-деревом, и там для этого много наворочено. А кому нужны первичные ключи по точкам?

Но если прям надо, то можно с помощью EXCLUDE сымитировать уникальность. Что-нибудь типа

EXCLUDE USING spgist(p WITH ~=)

А прикольно было бы всего Кнута так разрисовать.


Если серьезно, то добавить бы контекста про представленные алгоритмы. Скажем, в вашей реализации коллизии разрешаются переносом в соседнюю незанятую ячейку, но об этом можно только догадаться по самому коду. Ведь это не единственный способ. Нашел неприметную кнопку "Теория".

В мире (реляционных по крайней мере) СУБД действительно никогда не говорят о линеаризуемости, потому что она плохо сочетается с транзакциями. Одно дело, когда есть "точечные" события, которые можно выстроить одно за другим, а другое — когда есть продолжительные транзакции, части которых могут к тому же перепутываться с частями других транзакций. Поэтому сериализуемость — наше все.


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


Вы сейчас говорите, что всё же транзакция, начатая после завершения другой (можно ли это формализировать? happens after сообщения об успешности COMMIT?) точно будет в сериализуемом порядке после неё?

Да.


Если можете показать свои тесты, было бы интересно посмотреть.

Информация

В рейтинге
2 983-й
Откуда
Москва, Москва и Московская обл., Россия
Работает в
Дата рождения
Зарегистрирован
Активность