Оценка числа строк, статистика, условная стоимость и параметры запроса
Один SQL-запрос можно выполнить разными способами: прочитать таблицу целиком, пойти по индексу, сначала соединить маленькие таблицы или сначала отфильтровать большую. Планировщик перебирает допустимые варианты и выбирает план с наименьшей ожидаемой стоимостью.
План строится до выполнения запроса, поэтому сервер ещё не знает точное число подходящих строк. Он использует статистику и делает оценки.
Команда ANALYZE собирает статистику о данных. Среди прочего PostgreSQL хранит:
NULL;Планировщик также учитывает доступные индексы, ограничения и настройки относительной цены процессора, последовательного и случайного чтения.
В плане встречается запись вроде cost=10..120. Это не 120 миллисекунд.
cost — условные единицы внутренней модели, позволяющие сравнить варианты
между собой. Реальное время зависит от кеша, диска, параллельной нагрузки и
объёма данных, который нужно вернуть клиенту.
Кардинальность в плане — ожидаемое или фактическое количество строк. Получим план с реальным выполнением:
EXPLAIN (ANALYZE, BUFFERS, SETTINGS)
SELECT *
FROM marketplace.orders
WHERE org_id = 1 AND status = 'pending';Сравнивайте rows в оценке и actual rows в факте. Если узел выполнялся
несколько раз, учитывайте loops: общий объём примерно равен
actual rows × loops.
Первая большая ошибка в нижней части дерева часто важнее медленного верхнего узла. Она размножается выше и может заставить выбрать вложенный цикл вместо хеш-соединения или чтение по неподходящему индексу.
Обычная статистика хранится отдельно по столбцам. Планировщик может предположить,
что org_id и status независимы. Но у одной организации почти все заказы
могут быть pending, а у другой таких нет.
Для связанных столбцов создают расширенную статистику:
CREATE STATISTICS orders_org_status_stats
(dependencies, mcv)
ON org_id, status
FROM marketplace.orders;
ANALYZE marketplace.orders;dependencies описывает зависимости, а mcv — частые сочетания значений.
После ANALYZE планировщик точнее оценит совместное условие.
Расширенная статистика не является индексом и не ускоряет чтение напрямую. Она помогает выбрать более подходящий план.
Двигайтесь от причины к исправлению:
WHERE может потребовать статистики по выражению или индекса;Не повышайте объём статистики глобально без причины: это увеличит время
ANALYZE, размер каталога и работу планирования для всех таблиц.
Подготовленный запрос (prepared statement) — заранее разобранный SQL с
параметрами. Сначала PostgreSQL может строить отдельный план под конкретные
значения. После повторов он вправе перейти к общему плану, который не зависит
от параметра.
Если одна организация содержит половину таблицы, а другая — десять строк, один общий план может быть хорош для первой и плох для второй. Сравнивайте планы с реальными значениями параметров.
Настройка plan_cache_mode помогает диагностировать разницу общего и
индивидуального плана, но не должна быть первым постоянным исправлением.
В лаборатории 20 вы создадите связанные данные, увидите ошибку ожидаемого числа строк и исправите её расширенной статистикой.
Подробнее: как планировщик использует статистику.
Вопросы ещё не добавлены
Вопросы для этой подтемы ещё не добавлены.
Далее: EXPLAIN: как разбирать медленный запрос