linuxlab.io
Учебники▾
  • Линукс и сети
    Файловая система, процессы, TCP/IP, BGP и OSPF
    →
  • Terraform и IaC
    HCL, state, plan/apply на sandbox LocalStack
    →
  • Git и GitHub
    Объектная модель, plumbing, ветвление, GitHub Actions
    →
Все учебники →
ЦеныО платформеВойтиСоздать аккаунт
/
Intro
Lessons
Footer
linuxlab-УчебникиЦеныО платформеКонфиденциальность и куки
Copyright © 2026 LinuxLab. Все права защищены.
linuxlab.io
Учебники▾
  • Линукс и сети
    Файловая система, процессы, TCP/IP, BGP и OSPF
    →
  • Terraform и IaC
    HCL, state, plan/apply на sandbox LocalStack
    →
  • Git и GitHub
    Объектная модель, plumbing, ветвление, GitHub Actions
    →
Все учебники →
ЦеныО платформеВойтиСоздать аккаунт
/
  • Введение
  • Главы
  • How it worksскоро
  • Уроки
  • База знаний
  • Собеседование
home/postgres/lessons/pg-lab-29-1-join-order-geqo

lesson ── postgres-labs ── ~22 мин ── 4 шагов

Понаблюдай порядок соединений и кеш плана

Посмотрим на стоимость самого планирования и на кеш плана: как подготовленное выражение после нескольких вызовов переходит с custom на generic plan и как это вернуть назад. Запусти psql во вкладке client.

▶ интерактивный sandbox

Поднимется контейнер postgreslab/postgres-base с PostgreSQL 17 и psql. В браузере откроется терминал, база lab уже настроена. Каждый шаг проверяется автоматически. Сеть air-gapped, наружу контейнер не ходит.

запустить sandbox →

stack ── PostgreSQL 17 · psql · 1 GB RAM · air-gapped · самоуничтожается через 45 мин простоя

Шаги

  1. 01

    Сколько стоит планирование

    sql
    EXPLAIN ANALYZE
    SELECT t.passenger
    FROM tickets t
    JOIN flights f ON f.flight_id = t.flight_id
    JOIN bookings b ON b.book_ref = t.book_ref;

    Внизу - строки Planning Time и Execution Time. Их соотношение говорит, стоит ли кешировать план.

    подсказка

    Если планирование сопоставимо с выполнением - план стоит кешировать.

    ✓ Видно Planning Time против Execution Time.

  2. 02

    Пороги порядка соединений

    sql
    SHOW join_collapse_limit;   -- 8: сколько JOIN волен переставлять
    SHOW geqo_threshold;        -- 12: с какого числа таблиц включить GEQO

    До join_collapse_limit планировщик ищет лучший порядок; сверх - берёт как написано. От geqo_threshold включается генетический поиск.

    подсказка

    join_collapse_limit = 1 фиксирует порядок соединений вручную.

    ✓ Пороги на месте: 8 для перестановки JOIN, 12 для GEQO.

  3. 03

    Подготовленное выражение переходит на generic plan

    Подготовь выражение и выполни его много раз:

    sql
    PREPARE q(int) AS SELECT count(*) FROM tickets WHERE flight_id = $1;
    EXECUTE q(1);  -- повтори 8 раз
    SELECT name, generic_plans, custom_plans FROM pg_prepared_statements;

    Первые вызовы - custom plan под значение, после нескольких планировщик переходит на generic plan. Предскажи: будет ли generic_plans больше нуля?

    подсказка

    Переключение происходит примерно после 5 вызовов.

    ✓ generic_plans > 0 - выражение перешло на generic plan.

  4. 04

    Вернуть custom plan принудительно

    На перекошенных данных generic plan вреден. Заставь планировать каждый раз:

    sql
    SET plan_cache_mode = force_custom_plan;
    DEALLOCATE q;
    PREPARE q(int) AS SELECT count(*) FROM tickets WHERE flight_id = $1;
    EXECUTE q(1);  -- снова 8 раз
    SELECT generic_plans, custom_plans FROM pg_prepared_statements;

    Теперь generic_plans остаётся нулём - растёт только custom_plans.

    подсказка

    force_custom_plan платит временем планирования ради точного плана под значение.

    ✓ generic_plans = 0 - force_custom_plan планирует под значение каждый раз.

Что ты узнал

Порядок соединений ищется динамическим программированием до join_collapse_limit (8), дальше берётся как написано; от geqo_threshold (12) включается GEQO. Кеш плана: подготовленное выражение после ~5 вызовов может перейти на generic plan; на перекошенных данных его возвращают на custom через plan_cache_mode = force_custom_plan.

команды

  • SHOW join_collapse_limit;порог перестановки JOIN
  • SELECT generic_plans, custom_plans FROM pg_prepared_statements;счётчики кеша плана
  • SET plan_cache_mode = force_custom_plan;всегда планировать под значение

концепции

  • · число порядков соединения растёт быстрее факториала
  • · join_collapse_limit ограничивает перестановку, GEQO ищет порядок генетически
  • · после ~5 вызовов prepared может перейти на generic plan
  • · generic plan вреден на перекошенных данных - лечится force_custom_plan

← предыдущая

Получи hash, merge и nested loop на одном JOIN

следующая →

Расследуй плохой запрос и почини до Index Scan

Footer
linuxlab-
Copyright © 2026 LinuxLab. Все права защищены.
Учебники
Цены
О платформе
Конфиденциальность и куки