lesson ── postgres-labs ── ~22 мин ── 4 шагов
Стоимость - не магия, а арифметика. Достанем relpages и reltuples,
посчитаем стоимость Seq Scan по формуле и сверим с EXPLAIN до сотых.
Запусти psql во вкладке client.
интерактивный sandbox
Поднимется контейнер postgreslab/postgres-base с PostgreSQL 17 и psql. В браузере откроется терминал, база lab уже настроена. Каждый шаг проверяется автоматически. Сеть air-gapped, наружу контейнер не ходит.
stack ── PostgreSQL 17 · psql · 1 GB RAM · air-gapped · самоуничтожается через 45 мин простоя
SHOW seq_page_cost; -- 1.0
SHOW cpu_tuple_cost; -- 0.01
Это валюта планировщика: чтение страницы подряд = 1.0, обработка строки = 0.01.
За единицу взято последовательное чтение одной страницы.
✓ seq_page_cost = 1.0, как и ожидалось.
Обнови статистику и достань размеры:
ANALYZE tickets;
SELECT relpages, reltuples FROM pg_class WHERE relname = 'tickets';
Это число страниц и строк, на которые опирается формула.
relpages/reltuples обновляются при ANALYZE и VACUUM.
✓ Размеры известны: relpages и reltuples заполнены.
Посчитай руками: relpages * 1.0 + reltuples * 0.01. Запиши число.
Затем:
EXPLAIN SELECT * FROM tickets;
Второе число в cost=0.00..ЧИСЛО - твой результат. Совпало?
total cost = relpages × seq_page_cost + reltuples × cpu_tuple_cost.
✓ Seq Scan, и его total cost равен твоему расчёту.
EXPLAIN SELECT * FROM tickets ORDER BY ticket_no;
EXPLAIN SELECT * FROM tickets ORDER BY ticket_no LIMIT 5;
У узла Sort большой startup cost: чтобы отдать первую строку, надо отсортировать всё. С LIMIT планировщик смотрит на стоимость первых строк - и план может измениться.
startup cost - работа до первой строки; у Sort он большой.
✓ Виден большой startup у Sort - вот цена сортировки до первой строки.
Стоимость - условные единицы (чтение страницы подряд = 1.0). Seq Scan стоит relpages × seq_page_cost + reltuples × cpu_tuple_cost; результат сверяется с EXPLAIN до сотых. У каждого узла startup (до первой строки) и total (до всех) cost; LIMIT смещает выбор в пользу малого startup.
команды
SELECT relpages, reltuples FROM pg_class WHERE relname='t';размеры для формулыEXPLAIN SELECT * FROM t;сверить total cost с расчётомконцепции