Pull to refresh

Comments 14

Я не понял... в финальном запросе равенство вижу (на самом деле равенство по (sender_id, payment_type) = (444, 'СБП')), диапазон вижу (transaction_date < '2025-05-18' AND transaction_date > '2020-04-18')... а где обещанная сортировка?

Спасибо за замечание! Действительно, в финальном запросе используются равенства по (sender_id, payment_type) и диапазон по transaction_date, а явной сортировки (ORDER BY) в SQL-запросе нет.

Однако правило ESR (Equality → Sort → Range) применяется не к самому синтаксису запроса, а к логике построения составного B-tree индекса.

Под Sort здесь понимаются не только поля, указанные в ORDER BY, а вообще колонки, по которым может быть необходим упорядоченный обход — например, для работы с диапазонами или оптимизации последовательного доступа. Это особенно актуально, когда такие поля используются для отчетов или фильтров по времени.

В нашем случае порядок (sender_id, payment_type, transaction_date) соответствует схеме E → E → R (два равенства и один диапазон), что полностью соответствует ESR и позволяет PostgreSQL эффективно "обрезать" лишние страницы в глубине индекса при чтении.

Сортировку (ORDER BY) при желании можно добавить — и этот же индекс сработает корректно, потому что он уже построен в нужном порядке.

Я намеренно сосредоточился на структуре индекса, а не конкретной форме запроса, чтобы показать, в чём суть ESR и почему это работает.

Ну и финально: ESR — это общее практическое правило, применимое к широкому классу запросов, а не к одному конкретному синтаксису.

Ну так вы по сути-то ничего и НЕ показали. Точнее, показали какой-то кусок, обрывок.

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

Это - вопрос "включать или не включать поле в индекс". А вот как оно работает на именно последовательности Equality → Sort → Range, а не на совокупности Equality + Sort + Range, вы не показали. И как по мне - на текущий момент цель не достигнуто, а фактическое содержание не соответствует заявленному.

Уж если взялись - то показывайте, как работают ВСЕ компоненты правила. И главным образом - что сортировка перед фильтрацией по диапазону эффективнее, чем после. А желательно - ещё и с указанием, когда эта эмпирика не выполняется.

Вы, кажется, несколько переоцениваете формат статьи. Это практический материал — не технический стандарт и не академическая диссертация. ESR раскрыт в контексте задач, с которыми сталкиваются разработчики в реальных проектах, а не в рамках лабораторной работы на тему "распиши каждую букву".

Заявленная цель — показать, как порядок колонок в индексе влияет на производительность. Это показано. Конкретные значения, планы, замеры — всё на месте. Если вы ожидали чего-то другого — возможно, у вас были другие ожидания, а не у статьи другие цели.

И, честно говоря, разбирать "когда эмпирика не работает" — это уже задача читателя, если он претендует на уровень выше среднего. Материал и так даёт больше, чем большинство туторсов.

Так что если вы не нашли здесь то, что хотели — вполне возможно, вам просто не сюда)

Это показано.

Как по мне, то показано только то, что он - влияет. Как (эмпирика процесса), а уж тем более почему (физика процесса) - практически не затронуто.

А если по вашему мнению ответ на вопрос "как" - это просто выбор одного из вариантов "ускоряет", "замедляет" и "не влияет", пусть и с экспериментальным подтверждением,- то мы с вами и правда по-разному мыслим.

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

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

Ваши ожидания — это ваши ожидания. ;)
Это уже третий ответ - и, пожалуй, последний.)

Спасибо за статью, познавательно. Мне показалось что зря не покрыли ещё опцию Using при создании индекса. Пусть он и не участвует в описанных случаях, но тоже полезная инфа по работе с индексами.

Спасибо за комментарий!
Действительно, USING — важная часть при работе с другими типами индексов, вроде GIN или GiST. В этой статье решил сфокусироваться на B-tree и правиле ESR, но вы правы — хотя бы краткое упоминание USING было бы уместно. Возьму на заметку для следующего материала!

Спасибо за комментарий!
Интересная статья, в дополнение можно посмотреть выступления спикеров на форумах, перед написанием статьи увидел для себя несколько интересных в данном направлении.

Тема оптимизации сама по себе бесконечная)

Во-первых, в листах лежат указатели на записи.

Во-вторых, bitmap index scan возвращает указатели на страницы, на которых будут данные.

В-третьих, если поле в индексе, то оно там отсортировано уже. Идёт оно в начале или в конце не важно.

В-четвертых, поля в индексе должны идти по силе селективности. Самое не уникальное поле самое первое, т.д.

Во-первых, добрый день)

На первые два пункта я не возражаю — да, но значения также лежат.

На третий пункт прошу ещё раз прочитать мою статью: PostgreSQL не покажет и не напишет, какие поля он отсеял, а какие нет.

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

Добра вам!

Sign up to leave a comment.

Articles