
Задача
Исследовать и определить наиболее эффективный SQL-запрос, позволяющий получить информацию для анализа:
Неполных бронирований
Билетов без привязки к рейсам
Рейсов без процедуры посадки
Статистики по незавершённым операциям
Методология исследования
Тестовая среда и инструменты:
Тестовая ВМ: CPU = 8 / RAM = 8GB
Инструмент нагрузочного тестирования и статистического анализа производительности СУБД: pg_expecto
Тестовая база данных: "Демобаза 2.0" (большой размер, сложная схема)
Условия тестирования: параллельная нагрузка, ресурсоемкий запрос
СУБД: PostgreSQL 17
Конфигурационные параметры СУБД
track_io_timing = 'on'
listen_addresses = '0.0.0.0'
logging_collector = 'on'
log_directory = '/log/pg_log'
log_destination = 'stderr'
log_rotation_size = '0'
log_rotation_age = '1d'
log_filename = 'postgresql-%u.log'
log_line_prefix = '%m| %d| %a| %u| %h| %p| %e| '
log_truncate_on_rotation = 'on'
log_checkpoints = 'on'
archive_mode = 'on'
archive_command = 'true'
archive_timeout = '30min'
checkpoint_timeout = '15min'
checkpoint_warning = '60'
checkpoint_completion_target = '0.9'
min_wal_size = '2GB'
max_wal_size = '8GB'
synchronous_commit = 'on'
wal_compression = 'on'
random_page_cost = '1.1'
effective_io_concurrency = '300'
wal_sender_timeout = '0'
autovacuum_naptime = '1s'
autovacuum_vacuum_scale_factor = '0.01'
autovacuum_analyze_scale_factor = '0.005'
autovacuum_vacuum_cost_delay = '2ms'
autovacuum_max_workers = '4'
autovacuum_work_mem = '256MB'
vacuum_cost_limit = '4000'
bgwriter_delay = '10ms'
bgwriter_lru_multiplier = '4'
bgwriter_lru_maxpages = '400'
max_locks_per_transaction = '256'
max_pred_locks_per_transaction = '256'
shared_buffers = '1919MB'
effective_cache_size = '5757MB'
work_mem = '14MB'
temp_buffers = '14MB'
maintenance_work_mem = '479MB'
max_worker_processes = '8'
max_parallel_workers = '8'
max_parallel_workers_per_gather = '4'
idle_in_transaction_session_timeout = '1h'
statement_timeout = '8h'
pg_stat_statements.track_utility = 'off'
max_parallel_maintenance_workers = '4'
hash_mem_multiplier = '2'
autovacuum_vacuum_insert_scale_factor = '0.01'
shared_preload_libraries = 'pg_stat_statements , pg_wait_sampling'
commit_delay = '1000'
log_autovacuum_min_duration = '0'
wipe_file_on_delete = 'on'
wipe_heaptuple_on_delete = 'on'
wipe_mem_on_free = 'on'
wipe_memctx_on_free = 'on'
wipe_xlog_on_free = 'on'
log_connections = 'on'
log_disconnections = 'on'
pg_stat_statements.track = 'all'
max_connections = '1000'План нагрузочного тестирования (param.conf)
# НАСТРОЙКИ НАГРУЗОЧНОГО ТЕСТИРОВАНИЯ
# Максимальная нагрузка
finish_load = 20
# Тестовая БД
testdb = demo
# Веса сценариев
scenario1 = 1.0
Нагрузка на СУБД

Варианты SQL-запроса
LEFT JOIN
WITH random_period AS (
SELECT
start_date,
start_date + INTERVAL '30 days' AS end_date
FROM (
SELECT
book_date AS start_date
FROM bookings
WHERE book_date <= (SELECT MAX(book_date) FROM bookings) - INTERVAL '30 days'
ORDER BY RANDOM()
LIMIT 1
) AS random_date
)
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,
rp.start_date AS period_start,
rp.end_date AS period_end
FROM random_period rp
CROSS JOIN LATERAL (
SELECT *
FROM bookings b
WHERE b.book_date BETWEEN rp.start_date AND rp.end_date
) 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 boarding_passes bp ON
s.ticket_no = bp.ticket_no
AND s.flight_id = bp.flight_id
ORDER BY b.book_date, t.ticket_no;EXISTS
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
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 boarding_passes bp ON s.ticket_no = bp.ticket_no AND s.flight_id = bp.flight_id
WHERE EXISTS (
SELECT 1 FROM random_period rp
WHERE b.book_date BETWEEN rp.start_date AND rp.end_date
)
ORDER BY b.book_date, t.ticket_no;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)
AND (SELECT end_date FROM random_period)
)
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 filtered_bookings b
LEFT JOIN LATERAL (
SELECT ticket_no, passenger_name
FROM tickets
WHERE book_ref = b.book_ref
) t ON true
LEFT JOIN LATERAL (
SELECT flight_id, fare_conditions, price
FROM segments
WHERE ticket_no = t.ticket_no
) s ON true
LEFT JOIN LATERAL (
SELECT status, scheduled_departure, actual_departure, route_no
FROM flights
WHERE flight_id = s.flight_id
) f ON true
LEFT JOIN LATERAL (
SELECT seat_no, boarding_no
FROM boarding_passes
WHERE ticket_no = t.ticket_no AND flight_id = s.flight_id
) bp ON true
ORDER BY b.book_date, t.ticket_no;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 b.book_date BETWEEN (SELECT start_date FROM random_period)
AND (SELECT end_date FROM random_period)
GROUP BY b.book_ref, b.book_date
)
SELECT
bs.book_ref,
bs.book_date,
bs.ticket_count,
tn.ticket_no, -- Используем развернутое значение
t.passenger_name,
s.flight_id,
f.status
FROM booking_summary bs
CROSS JOIN UNNEST(bs.ticket_numbers) AS tn(ticket_no) -- Разворачиваем массив здесь
LEFT JOIN tickets t ON t.ticket_no = tn.ticket_no -- Теперь соединяем по одиночному значению
LEFT JOIN segments s ON s.ticket_no = t.ticket_no
LEFT JOIN flights f ON f.flight_id = s.flight_id
ORDER BY bs.book_date, tn.ticket_no; -- Сортируем по развернутому значениюTEMPORARY TABLE (Временная таблица)
-- Создаем временную таблицу для отфильтрованных бронирований
CREATE TEMPORARY TABLE temp_filtered_bookings AS
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.*
FROM bookings b
CROSS JOIN random_period rp
WHERE b.book_date BETWEEN rp.start_date AND rp.end_date;
-- Создаем индексы на временной таблице
CREATE INDEX tmp_idx_book_ref ON temp_filtered_bookings (book_ref);
CREATE INDEX tmp_idx_book_date ON temp_filtered_bookings (book_date);
--TEST-5 "TEMP TABLES"
EXPLAIN (ANALYZE , SUMMARY , COSTS)
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 boarding_passes bp ON s.ticket_no = bp.ticket_no AND s.flight_id = bp.flight_id
ORDER BY b.book_date, t.ticket_no;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
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 boarding_passes bp ON s.ticket_no = bp.ticket_no AND s.flight_id = bp.flight_id
WHERE b.book_date BETWEEN rp.start_date AND rp.end_date
AND (f.status IS NULL OR f.status IN ('Scheduled', 'On Time', 'Departed')) -- Фильтр по статусу
ORDER BY b.book_date, t.ticket_no;Дополнение
Для варианта "TEMPORARY TABLE (Временная таблица)" - временная таблица temp_filtered_bookings пересоздается перед выполнением тестового запроса.
Эксперименты
Вариант-1: Использование EXISTS
Вариант-2: Оптимизация структуры запроса
Вариант-3: Частичная агрегация
Вариант-4: Использование временных таблиц
Характерные особенности тестовых запросов и планов выполнения
1. LEFT JOIN
Особенности:
Использует CROSS JOIN LATERAL для фильтрации
Сложная структура с множеством вложенных соединений
Большие объемы сортировки на диске (121 MB)
Проблемы:
Многоуровневое вложение соединений
Неоптимальная последовательность JOIN
Высокий объем временных данных
2. EXISTS
Особенности:
Использует подзапрос EXISTS для фильтрации
Semi Join с фильтрацией строк (Rows Removed: 6,721,707)
Последовательное сканирование всей таблицы bookings
Проблемы:
Сканирование 7+ миллионов строк для фильтрации
Высокая стоимость Join Filter
Неэффективное использование индексов
3. TUNNING
Особенности:
Использует CTE с предварительной фильтрацией
LEFT JOIN LATERAL для последовательного соединения
Параллельное выполнение (Gather Merge)
Разделение на filtered_bookings
Преимущества:
Ранняя фильтрация данных
Оптимальная последовательность JOIN
Использование параллелизма
Наименьший объем дисковых операций (50 MB)
4. ARRAY
Особенности:
Использует агрегацию ARRAY_AGG и UNNEST
Мемоизация (кэширование) данных tickets
Параллельная агрегация
Проблемы:
Двойная работа с таблицей tickets
Высокие промахи кэша (Misses: 821,542)
Сложная структура с развертыванием массива
5. TEMP TABLE
Особенности:
Создание временной таблицы с индексами
Предварительная фильтрация во временной таблице
Использование индексов на временной таблице
Преимущества:
Повторное использование отфильтрованных данных
Эффективные индексы для JOIN
Упрощение основного запроса
Недостатки:
Накладные расходы на создание таблицы
Дополнительное управление транзакциями
6. WHERE
Особенности:
Простая фильтрация в WHERE
Параллельное выполнение
Дополнительные фильтры по статусу
? Принципиальные различия, влияющие на производительность
1. Стратегия фильтрации:
Хорошо: Ранняя фильтрация (TUNNING, TEMP TABLE) - уменьшает объем обрабатываемых данных
Плохо: Поздняя фильтрация (EXISTS, WHERE) - обрабатывает все строки перед фильтрацией
2. Использование индексов:
Эффективно: Индексные сканы по book_date (TUNNING, LEFT JOIN)
Неэффективно: Sequential Scan (EXISTS, ARRAY на полной таблице)
3. Параллелизм:
Есть: TUNNING, ARRAY, WHERE - используют параллельное выполнение
Нет: LEFT JOIN, EXISTS, TEMP TABLE - последовательное выполнение
4. Структура соединений:
Оптимально: Последовательные LATERAL JOIN (TUNNING)
Сложно: Многоуровневые вложенные JOIN (LEFT JOIN)
5. Управление памятью:
Хорошо: External Merge с меньшим объемом (TUNNING - 50 MB)
Плохо: Большие дисковые сортировки (LEFT JOIN - 121 MB)
? Ключевой вывод
Подход TUNNING демонстрирует наилучший баланс производительности и читаемости:
Дисковые операции: 50 MB (на 60% меньше LEFT JOIN)
Использование параллелизма: Gather Merge
Четкая последовательность операций
Второй по эффективности - подход TEMP TABLE, который особенно полезен при:
Многократном использовании отфильтрованных данных
Сложных цепочках преобразований
Необходимости разделения логики запроса
Нагрузка на СУБД

Производительность СУБД в ходе нагрузочного тестирования

Тестовый запрос "WHERE" - деградация производительности, при нагрузке 15 сессий и выше (точка наблюдения - 81)
Характерные особенности производительности СУБД, для нагрузки 15 соединений и выше
1. Производительность
Запрос |
Средняя производительность |
Динамика |
Стабильность |
ARRAY |
32 |
Стабильно высокая |
⭐⭐⭐⭐⭐ |
TUNNING |
22 |
Стабильная |
⭐⭐⭐⭐ |
WHERE |
10 → 0 |
Резкое падение |
⭐ |
EXISTS |
12-14 |
Умеренная |
⭐⭐ |
LEFT JOIN |
14-16 |
Умеренная |
⭐⭐ |
Вывод: ARRAY и TUNNING демонстрируют наилучшую и стабильную производительность.
2. Ввод-вывод (IO) - нагрузка на систему
Запрос |
Значение IO |
Тренд |
Интенсивность |
TUNNING |
21151 → 44556 |
Резкий рост |
? Высокая |
TEMP TABLE |
17314 → 22882 |
Умеренный рост |
? Средняя |
LEFT JOIN |
12330 → 15183 |
Умеренный рост |
? Средняя |
EXISTS |
11725 → 14426 |
Умеренный рост |
? Средняя |
ARRAY |
5436 → 8368 |
Умеренный рост |
? Низкая |
WHERE |
6043 → 7928 |
Медленный рост |
? Низкая |
Вывод: TUNNING создает самую высокую нагрузку на ввод-вывод, но при этом сохраняет высокую производительность.
3. Межпроцессное взаимодействие (IPC)
Запрос |
Значение IPC |
Особенность |
LEFT JOIN |
13145 → 24107 |
⚠️ Очень высокий, устойчивый рост |
EXISTS |
12515 → 21728 |
⚠️ Высокий, значительный рост |
WHERE |
3134 → 4329 |
Умеренный |
TEMP TABLE |
5592 → 5870 |
Стабильный |
TUNNING |
868 → 2670 |
Умеренный рост |
ARRAY |
110 → 101 |
⭐ Очень низкий |
Вывод: LEFT JOIN и EXISTS создают чрезмерную нагрузку на IPC, что указывает на неэффективное межпроцессное взаимодействие.
4. Легковесные блокировки (LWLOCK)
Запрос |
Значение LWLOCK |
Динамика |
TEMP TABLE |
38 → 311 |
⚠️ Экстремальный рост |
ARRAY |
44 → 227 |
Значительный рост |
WHERE |
33 → 247 |
Значительный рост |
LEFT JOIN |
50 → 106 |
Умеренный рост |
EXISTS |
53 → 99 |
Умеренный рост |
TUNNING |
14 → 19 |
⭐ Минимальный рост |
Вывод: TEMP TABLE вызывает наибольшее количество легковесных блокировок, что связано с управлением временными объектами.
5. Таймауты (TIMEOUT)
Запрос |
Значение TIMEOUT |
Стабильность |
WHERE |
7 → 30 |
⚠️ Критический рост |
LEFT JOIN |
10 → 19 |
Умеренный рост |
EXISTS |
8 → 14 |
Умеренный рост |
TEMP TABLE |
4 → 8 |
Умеренный рост |
ARRAY |
1 → 5 |
Минимальный рост |
TUNNING |
2 → 3 |
⭐ Максимальная стабильность |
Вывод: WHERE показывает наихудшие показатели по таймаутам, что указывает на проблемы с выполнением запроса.
? Ключевые особенности каждого подхода
1. ARRAY - ЛУЧШИЙ ПО ПРОИЗВОДИТЕЛЬНОСТИ
-
Преимущества:
Максимальная и стабильная скорость
Самый низкий IPC
Умеренные таймауты
-
Недостатки:
Высокие LWLOCK
Умеренный рост IO
2. TUNNING - ЛУЧШИЙ ПО СТАБИЛЬНОСТИ
-
Преимущества:
Стабильная производительность
Минимальные LWLOCK
Самые низкие таймауты
-
Недостатки:
Очень высокий IO
Умеренный рост IPC
3. TEMP TABLE - ВЫСОКАЯ ЦЕНА УПРАВЛЕНИЯ
-
Особенности:
Экстремальный рост LWLOCK
Стабильный IPC
Умеренные таймауты
Вывод: Подходит для изолированных операций, но создает высокую нагрузку на блокировки
4. LEFT JOIN & EXISTS - ПРОБЛЕМЫ С IPC
-
Общие проблемы:
Очень высокий IPC
Умеренная производительность
Значительные таймауты
Вывод: Неэффективное межпроцессное взаимодействие снижает производительность
5. WHERE - КАТАСТРОФИЧЕСКОЕ ПАДЕНИЕ
-
Критические проблемы:
Операционная скорость падает до 0
Таймауты взрывные
Высокие LWLOCK
Вывод: Непригоден для нагрузочного тестирования
? Итоговые рекомендации
Для максимальной производительности:
Используйте ARRAY подход - обеспечивает самую высокую скорость
Используйте TUNNING подход - обеспечивает максимальную стабильность
Для оптимизации инфраструктуры:
Мониторинг IPC: для LEFT JOIN и EXISTS
Контроль LWLOCK: для TEMP TABLE и ARRAY
Избегайте WHERE подхода в высоконагруженных системах
Итог: Подходы ARRAY и TUNNING демонстрируют наилучший баланс производительности и системных нагрузок, в то время как WHERE категорически не подходит для высоконагруженных систем.
Метрики производительности инфраструктуры для нагрузки 15 соединений и выше
1. "LEFT JOIN"
Процессы: procs_r колеблется от 4 до 9, procs_b остаётся в основном на уровне 1–2.
Память: swpd стабилен (~217), free ~179–180, buff ~10–27, cache ~6890–7069.
Ввод/вывод: bi высокий (66000–73000), bo умеренный (3474–4205).
Системные вызовы: in ~10449–13884, cs ~9511–13622.
CPU: us ~35–56%, sy ~4–5%, id ~17–47%, wa ~11–17%.
Особенности: Нагрузка на CPU (us) растёт, особенно к концу теста. wa остаётся умеренным, что указывает на приемлемую нагрузку на диск. Заметен рост системных вызовов (in, cs) к точкам 105–110.
2. "EXISTS"
Процессы: procs_r 7–9, procs_b 1–2.
Память: swpd ~212–217, free ~180–181, buff ~7, cache ~6970–7137.
Ввод/вывод: bi ~63848–77743, bo ~2276–4977.
Системные вызовы: in ~10030–14105, cs ~9967–13579.
CPU: us ~36–63%, sy ~4–5%, id ~15–46%, wa ~11–15%.
Особенности: Нагрузка на CPU (us) возрастает до 63% к концу теста. wa снижается до 12–13% после точки 90, что может говорить об оптимизации операций ввода-вывода.
3. "TUNNING"
Процессы: procs_r 7–8, procs_b увеличивается до 3–7 (много заблокированных процессов).
Память: swpd ~204, free ~179–185, buff ~105–147, cache ~6701–6951.
Ввод/вывод: bi ~42442–73802, bo ~3800–11145.
Системные вызовы: in ~7062–9575, cs ~3175–4974.
CPU: us ~46–66%, sy ~3–5%, id ~3–36%, wa ~12–28%.
Особенности: Очень высокий wa (до 28%) и низкий id (до 3%), что указывает на сильную нагрузку на ввод-вывод. Много заблокированных процессов (procs_b до 7) свидетельствует о проблемах с дисковой подсистемой.
4. "ARRAY"
Процессы: procs_r 10–15, procs_b 0–1.
Память: swpd ~222–237, free ~174–296, buff ~3–124, cache ~5973–6613.
Ввод/вывод: bi ~12455–34691, bo ~3569–22406.
Системные вызовы: in ~6324–9509, cs ~1505–2568.
CPU: us ~59–95%, sy ~2–4%, id ~0–36%, wa ~0–3%.
Особенности: Очень высокий us (до 95%) при низком wa — нагрузка процессорная, а не дисковая. id падает до 0% в некоторых точках, что говорит о полной загрузке CPU.
5. "TEMP TABLE"
Процессы: procs_r 8–13, procs_b 1.
Память: swpd ~226–243, free ~170–364, buff ~2–54, cache ~6099–6887.
Ввод/вывод: bi ~57009–59628, bo ~8307–26681.
Системные вызовы: in ~8748–11622, cs ~5720–7777.
CPU: us ~42–80%, sy ~4–6%, id ~2–40%, wa ~7–16%.
Особенности: Умеренные значения us и wa. После точки 90 wa снижается до 7–9%, а us растёт до 80%, что может указывать на эффективное использование временных таблиц.
6. "WHERE"
Процессы: procs_r 10–15, procs_b = 0 .
Память: swpd ~212, free ~188–198, buff ~123–145, cache ~6189–6615.
Ввод/вывод: bi ~146134–252075, bo ~190616–276018.
Системные вызовы: in ~7306–9652, cs ~1664–3320.
CPU: us ~52–80%, sy ~9–14%, id ~1–34%, wa ~1–3%.
Особенности: Очень высокие bi и bo, но при этом низкий wa (1–3%), что может указывать на эффективное кэширование или быструю дисковая подсистему. Нагрузка на CPU (us) высокая, id низкий.
Сводная таблица по метрикам vmstat
Запрос |
Нагрузка на CPU ( |
Нагрузка на I/O ( |
Особенности |
LEFT JOIN |
Умеренная (35–56%) |
Умеренная (11–17%) |
Рост системных вызовов к концу теста. |
EXISTS |
Высокая (до 63%) |
Умеренная (11–17%) |
Снижение |
TUNNING |
Высокая (до 66%) |
Очень высокая (до 28%) |
Много заблокированных процессов, проблемы с I/O. |
ARRAY |
Очень высокая (до 95%) |
Низкая (0–3%) |
Полная загрузка CPU, минимальная нагрузка на диск. |
TEMP TABLE |
Высокая (до 80%) |
Умеренная (7–16%) |
Снижение |
WHERE |
Высокая (до 80%) |
Низкая (1–3%) |
Высокий I/O, но эффективная обработка (низкий |
Выводы:
"ARRAY" и "WHERE" демонстрируют процессорную нагрузку с минимальными задержками на I/O.
"TUNNING" явно страдает от медленного I/O, что видно по высокому
waи заблокированным процессам."EXISTS" и "LEFT JOIN" показывают сбалансированную нагрузку с умеренным использованием CPU и диска.
"TEMP TABLE" эффективно использует временные структуры, снижая нагрузку на диск к концу теста.
P.S. Следующий цикл публикация будет посвящен способам пагинации.
khalimonas
Думаю неплохим тоном было бы сохранять логику запросов единой, хоть это и мало влияет на анализ производительности.
pg_expecto Автор
Просьба уточнить тезис
khalimonas
в одних запросах выбирается строго 30тидневные периоды, в других от 1 до 30
pg_expecto Автор
это условие эксперимента - входные данные случайны.
Поскольку СУБД по сути своей есть стохастическая система.
khalimonas
Входные данные случайны - безусловно. Но вы изначально для одних запросов выбираете усреднено максимальный объем, а для других плавающий, от 3% до 100% от максимального. Это не условие эксперимента, это методологическая ошибка.
pg_expecto Автор
Я кажется понял суть, вашего замечания.
Нет, ошибки , тем более методологической - нет. Есть неполное описание эксперимента.
Кратко - тестовый запрос выполняется внутри хранимой функции, перед выполнением запроса для эксперимента с временной таблицей - временная таблица пересоздается. Для тестового запроса в любом эксперименте входные данные по периоду - случайны. В том числе и для эксперимента с использованием временной таблицы.
Дополню статью .
Спасибо за замечание.