Материал для ознакомления. Один из экспериментов поставлен некорректно. Исправленный вариант ————— Предисловие Оптимизировать запрос в вакууме — просто. Но как он поведет себя, когда десятки таких же запросов одновременно борются за ресурсы? Бизнес задача Подготовить наиболее эффективный SQL-запрос, позволяющий получить информацию для анализа: Неполных бронирований Билетов без привязки к рейсам Рейсов без процедуры посадки Статистики по незавершённым операциям Методология исследования Тестовая среда и инструменты: СУБД: PostgreSQL 17 Инструмент нагрузочного тестирования: pg_expecto Тестовая база данных: "Демобаза 2.0" (большой размер, сложная схема) Условия тестирования: параллельная нагрузка, ресурсоемкий запрос Протестированные решения LEFT JOIN EXISTS TUNING(оптимизация структуры запроса) ARRAY(Частичная агрегация) ❌TEMPORARY TABLE (Временная таблица) WHERE (Изменение условия WHERE) Эксперименты Нагрузка на СУБД Производительность СУБД в ходе нагрузочного тестиро
Материал для ознакомления. Один из экспериментов поставлен некорректно. Исправленный вариант ————— Предисловие Оптимизировать запрос в вакууме — просто. Но как он поведет себя, когда десятки таких же запросов одновременно борются за ресурсы? Бизнес задача Подготовить наиболее эффективный SQL-запрос, позволяющий получить информацию для анализа: Неполных бронирований Билетов без привязки к рейсам Рейсов без процедуры посадки Статистики по незавершённым операциям Методология исследования Тестовая среда и инструменты: СУБД: PostgreSQL 17 Инструмент нагрузочного тестирования: pg_expecto Тестовая база данных: "Демобаза 2.0" (большой размер, сложная схема) Условия тестирования: параллельная нагрузка, ресурсоемкий запрос Протестированные решения LEFT JOIN EXISTS TUNING(оптимизация структуры запроса) ARRAY(Частичная агрегация) ❌TEMPORARY TABLE (Временная таблица) WHERE (Изменение условия WHERE) Эксперименты Нагрузка на СУБД Производительность СУБД в ходе нагрузочного тестиро
...Читать далее
Материал для ознакомления. Один из экспериментов поставлен некорректно.
Исправленный вариант
—————
Предисловие
Оптимизировать запрос в вакууме — просто. Но как он поведет себя, когда десятки таких же запросов одновременно борются за ресурсы?
Бизнес задача
Подготовить наиболее эффективный SQL-запрос, позволяющий получить информацию для анализа:
- Неполных бронирований
- Билетов без привязки к рейсам
- Рейсов без процедуры посадки
- Статистики по незавершённым операциям
Методология исследования
Тестовая среда и инструменты:
- СУБД: PostgreSQL 17
- Условия тестирования: параллельная нагрузка, ресурсоемкий запрос
Протестированные решения
LEFT JOIN
Таблицы используемые в тестовом запросе demo=# \d bookings Unlogged table "bookings.bookings" Column | Type | Collation | Nullable | Default --------------+--------------------------+-----------+----------+--------- book_ref | character(6) | | not null | book_date | timestamp with time zone | | not null | total_amount | numeric(10,2) | | not null | Indexes: "bookings…
Postgres DBA29 ноября 2025
EXISTS
План выполнения тестового запроса - EXISTS Sort (cost=2920577.58..2926299.37 rows=2288716 width=77) (actual time=52126.170..52366.389 rows=1076571 loops=1) Sort Key: b.book_date, t.ticket_no Sort Method: external merge Disk: 97592kB CTE random_period -> Limit (cost=191879.84..191879.84 rows=1 width=24) (actual time=4368.349..4368.353 rows=1 loops=1) -> Sort (cost…
Postgres DBA29 ноября 2025
TUNING(оптимизация структуры запроса)
Тестовый запрос - TUNING WITH random_period AS ( SELECT book_date AS start_date, book_date + INTERVAL '30 days' AS end_date FROM bookings WHERE book_date <= (SELECT MAX(book_date) FROM bookings) - INTERVAL '30 days' ORDER BY RANDOM() LIMIT 1 ), filtered_bookings AS ( SELECT book_ref, book_date FROM bookings WHERE book_date BETWEEN (SELECT start_date FROM random_period…
Postgres DBA30 ноября 2025
ARRAY(Частичная агрегация)
Тестовый запрос -ARRAY WITH random_period AS ( SELECT book_date AS start_date, book_date + INTERVAL '30 days' AS end_date FROM bookings ORDER BY RANDOM() LIMIT 1 ), booking_summary AS ( SELECT b.book_ref, b.book_date, COUNT(t.ticket_no) as ticket_count, ARRAY_AGG(t.ticket_no) as ticket_numbers FROM bookings b LEFT JOIN tickets t ON b.book_ref = t.book_ref WHERE…
Postgres DBA30 ноября 2025
❌TEMPORARY TABLE (Временная таблица)
--Тестовый запрос - TEMPORARY TABLE SELECT b.book_ref, b.book_date, t.ticket_no, t.passenger_name, s.flight_id, f.status, f.scheduled_departure, f.actual_departure, bp.seat_no, bp.boarding_no FROM temp_filtered_bookings b LEFT JOIN tickets t ON b.book_ref = t.book_ref LEFT JOIN segments s ON t.ticket_no = s.ticket_no LEFT JOIN flights f ON s.flight_id = f.flight_id LEFT JOIN…
Postgres DBA1 декабря 2025
WHERE (Изменение условия WHERE)
Тестовый запрос - WHERE WITH random_period AS ( SELECT book_date AS start_date, book_date + INTERVAL '30 days' AS end_date FROM bookings ORDER BY RANDOM() LIMIT 1 ) SELECT b.book_ref, b.book_date, t.ticket_no, t.passenger_name, s.flight_id, f.status, f.scheduled_departure, f.actual_departure, bp.seat_no, bp.boarding_no FROM bookings b CROSS JOIN random_period rp…
Postgres DBA2 декабря 2025
Эксперименты
Нагрузка на СУБД
Производительность СУБД в ходе нагрузочного тестирования
График изменения операционной скорости в ходе нагрузочного тестирования
Характерные особенности производительности СУБД для нагрузки 15 соединений и выше
❓Проанализируй данные производительности(чем выше значение тем выше производительность) в ходе нагрузочного тестирования для разных тестовых запросов . Выдели ключевые особенности после точки измерения 81.
1. Катастрофическое падение производительности тестового запроса "WHERE"
- Резкое снижение: Значения колеблются (12-16), затем происходит обвал до 4, после 18 соединений — до 2, а с нагрузки 22 соединения производительность полностью деградирует.
- Важность: Падение до 0 означает, что эти запросы фактически перестают выполняться.
2. Стабилизация и рост производительности "JOIN"
- Положительный тренд: После 15 соединений "JOIN" показывает стабильные значения 14, а после 18 соединений производительность возрастает до 16.
3. Улучшение "EXISTS"
- Рост производительности: С 18 соединений значение увеличивается с 12 до 14 и остается стабильным.
4. Стабильность "TUNING"
- Консистентность: После 15 соединений производительность стабильно держится на уровне 22.
5. "ARRAY"- максимальная стабильность
- Идеальная стабильность: После 12 соединений производительность достигает своего максимального стабильного значения 32.
6. "TEMP TABLE" высокая производительность
- Высокий уровень: Значения 214-216 (самые высокие абсолютные значения).
Критические выводы:
- Наиболее уязвимый компонент: "WHERE"- сильная деградация под нагрузкой.
- Наиболее устойчивые: "ARRAY" и "TUNING" запросы показывают отличную стабильность.
- Парадокс: В то время как "WHERE" деградируют до 0, другие типы запросов либо стабильны, либо улучшаются. Это может указывать на:
- Конкуренцию за ресурсы
- Проблемы специфические для условий "WHERE"
Метрики производительности инфраструктуры для нагрузки 15 соединений и выше
❓Проанализируй показатели метрик vmstat в ходе нагрузочного тестирования для разных тестовых запросов . Выдели ключевые особенности по метрикам wa , bi , us , r , cache , sy , si после точки измерения 81.
1. WA (Ожидание ввода-вывода) - CPU Wait I/O
- JOIN: высокий уровень (11-16%), особенно в конце (до 17%)
- EXISTS: умеренный (12-15%), относительно стабильный
- TUNING: самый высокий (24-28%) - явная проблема с дисковыми операциями
- ARRAY: минимальный (0-3%) - низкая нагрузка на I/O
- TEMPORARY TABLE: минимальный (0-1%)
- WHERE: низкий (1-3%)
2. BI (Blocks In - блоки ввода)
- JOIN: высокий (66K-86K)
- EXISTS: умеренный (68K-86K)
- TUNING: высокий (69K-73K)
- ARRAY: средний (32K-35K)
- TEMPORARY TABLE: средний (62K-63K)
- WHERE: экстремально высокий (200K-250K) - интенсивное чтение с диска
3. US (User CPU - пользовательский процессор)
- JOIN: умеренный (54-58%)
- EXISTS: умеренный (56-64%)
- TUNING: высокий (59-66%)
- ARRAY: очень высокий (94-95%)
- TEMPORARY TABLE: очень высокий (93-95%)
- WHERE: высокий (80%)
4. R (Run Queue - очередь процессов)
- JOIN: 7-9 процессов
- EXISTS: 7-10 процессов
- TUNING: 7-8 процессов
- ARRAY: 11-15 процессов
- TEMPORARY TABLE: 13-15 процессов
- WHERE: 12-15 процессов
5. CACHE (Кэш памяти)
- JOIN: стабильно высокий (6800-7100)
- EXISTS: стабильно высокий (6800-7000)
- TUNING: стабильно высокий (6700-6900)
- ARRAY: снижается (6000-6300)
- TEMPORARY TABLE: умеренный (6400-6600)
- WHERE: умеренный (6100-6300)
6. SY (System CPU - системный процессор)
- JOIN: низкий (5%)
- EXISTS: низкий (5%)
- TUNING: низкий (5%)
- ARRAY: низкий (4%)
- TEMPORARY TABLE: низкий (5%)
- WHERE: высокий (12-14%) - интенсивные системные вызовы
7. SI (Swap In)
Данные по SI отсутствуют в предоставленном файле.
Ключевые выводы:
- Наиболее проблемный запрос: "TUNING" - имеет максимальное время ожидания I/O (24-28%) при умеренной нагрузке CPU.
- Наиболее CPU-интенсивные запросы: "ARRAY" и "TEMPORARY TABLE" - достигают 95% использования user CPU.
- Наиболее I/O-интенсивный запрос: "WHERE" - экстремально высокий BI (до 250K) и повышенное системное время CPU (14%).
- Наибольшая очередь выполнения: "ARRAY", "TEMPORARY TABLE" и "WHERE" (11-15 процессов).
- Наименее нагруженные запросы: "JOIN" и "EXISTS" показывают сбалансированные метрики без экстремальных значений.
Итог
Производительность СУБД
- Для данной СУБД и в условиях высокой конкурентной нагрузки, для обеспечения максимальной производительности - рекомендован паттерн "ТEMPORARY TABLE"
- Наихудший паттерн - "WHERE"
Производительность и стабильность инфраструктуры
- Для данной СУБД и в условиях высокой конкурентной нагрузки, для обеспечения стабильной работы инфраструктуры, если производительность запроса не является ключевым требованием - рекомендованы паттерны "JOIN" и "EXISTS".
- Наихудший паттерн - "WHERE"