TGViewer
SQL Portal | Базы Данных SQL Portal | Базы Данных @sqlportal · 13.7K subscribers
Post #1850 1.45K
Написать медленный запрос в Postgres сегодня гораздо сложнее, чем раньше. Запрос может содержать полное сканирование таблицы, крупную сортировку или дорогую агрегацию, но всё равно выполняться быстро. Современный Postgres просто подключает параллельных воркеров.

Параллелизм скрывает стоимость тяжёлых запросов, но не устраняет её. Индексы и механизмы кэширования уменьшают объём работы, который нужно выполнить.

Параллельное выполнение всё равно делает тот же объём работы — оно лишь распределяет его между несколькими процессорами. Воркеры позволяют задействовать больше CPU, но не сокращают количество операций. Если запрос выполняет полное сканирование таблицы, он всё равно прочитает всю таблицу. Просто сделает это быстрее за счёт дополнительных CPU.
На первый взгляд безобидный запрос:

SELECT
user_id,
count(*) AS total_events
FROM events
GROUP BY user_id
ORDER BY total_events DESC
LIMIT 10;


Предположим, что индексов нет, таблица events содержит 1 000 000 строк и 10 000 уникальных user_id. Такой запрос выполняет большой объём работы. В любом случае ему придётся прочитать каждую строку таблицы.
Параллельный конвейер Postgres

Postgres разделил таблицу на три части, выполнил агрегацию параллельно и затем объединил результаты.
[см. изображение с выводом EXPLAIN ANALYZE]

loops=3 для Seq Scan
Workers Launched: 2 (лидирующий процесс + 2 воркера = всего 3 процесса)
Partial HashAggregate выполняется в каждом воркере
результаты объединяются через Finalize HashAggregate в лидирующем процессе

Несмотря на высокую скорость выполнения, это не лучший вариант для OLTP-базы данных.
При высокой конкурентной нагрузке пул воркеров становится узким местом. Запрос может работать быстро, пока ресурсов хватает, но заметно замедляться при конкуренции за CPU. Запросы с нестабильным временем выполнения — хорошие кандидаты для оптимизации.

Параллельные воркеры не заменяют здоровую архитектуру базы данных:
Добавляйте индексы, чтобы избежать полного сканирования таблиц и дорогостоящих сортировок.
Используйте summary-таблицы или materialized view, чтобы не выполнять тяжёлые агрегации на больших объёмах данных.
Разбивайте time-series таблицы на партиции, чтобы уменьшить объём данных, который приходится сканировать в типовых запросах.

👉 @SQLPortal
More from @sqlportal
  1. Oct 9, 2026Горизонтальные или вертикальные столбцы: что выбрать? Оба варианта помогают сравнивать кат…
  2. Oct 9, 2026Оконные функции SQL: аналитика без потери отдельных строк В отличие от GROUP BY, оконные ф…
  3. Oct 8, 2026DBcooper — лёгкий клиент для работы с базами данных Open-source-приложение на Tauri, Rust…
  4. Oct 8, 20265 групп реляционных СУБД, которые полезно знать • С открытым исходным кодом: PostgreSQL, M…
  5. Oct 7, 2026Разбираем SQL-запросы с помощью Python Какие таблицы и колонки использует запрос? Библиоте…
  6. Oct 7, 2026Линтер и автоформаттер для SQL Бесплатный инструмент с открытым исходным кодом, который пр…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →