Проект сравнивает PostgreSQL 17, MySQL 8.4 и MongoDB 8.0 на одном и том же наборе данных student_activity. Цель исследования — показать, когда индексы действительно ускоряют запросы, когда эффект слабый, а когда индексы дают накладные расходы.
Для всех трех СУБД используются одинаковые ресурсные ограничения Docker Compose:
cpus: "2.0"
mem_limit: "3g"Используется синтетический журнал учебной активности студентов. Основные поля:
activity_id— идентификатор события;student_id— идентификатор студента;course_id— идентификатор курса;faculty— факультет;group_code— учебная группа;activity_type— тип учебной активности;status— статус события;score— оценка или числовой результат;created_at— дата создания события;updated_at— дата обновления события;semester— семестр.
По умолчанию генерируется 1_000_000 строк. Seed не является обязательной частью методики. Если нужен точный повтор конкретного датасета, можно явно передать --seed. После генерации сохраняется файл data/student_activity_metadata.json с фактически использованным seed.
Сравниваются семь типовых сценариев:
Q1— поиск поstudent_id;Q2— фильтрация по диапазонуcreated_at;Q3— фильтрация поstatus;Q4— фильтрация поstatusиcreated_at;Q5— сортировка поcreated_at DESCсLIMIT 100;Q6— агрегация поcourse_idдля записей со статусомgraded;Q7— широкий диапазонscore, где индекс должен помогать слабо или не помогать вовсе.
Константы запросов зафиксированы в scripts/config.py.
Проект сравнивает не только режимы “без индексов” и “со всеми индексами”, но и отдельные конфигурации:
no_indexesidx_student_id_onlyidx_created_at_onlyidx_status_onlyidx_status_created_at_onlyidx_course_score_onlyall_indexes
Идея такая:
- оценить, какой индекс помогает какому запросу;
- проверить, есть ли лишние индексы;
- увидеть случаи, где индекс почти не помогает или ухудшает результат.
Актуальные параметры измерений по умолчанию:
warmup_runs = 0
measured_runs = 1000
Все 1000 измеряемых запусков сохраняются в results/benchmark_results.csv. По ним считаются:
medianmeanminmaxstdp95p99
После полного запуска python scripts/run_all.py создаются такие основные артефакты:
results/benchmark_results.csv— все измеряемые прогоныСУБД × конфигурация индексов × запрос;results/benchmark_stats.csv— агрегированная статистика по каждой группе;results/benchmark_medians.csv— медианы по каждой группе, используемые для производных Q1-выводов;results/index_effectiveness.csv— сравнение каждой конфигурации сno_indexes;results/load_performance.csv— время загрузки данных без индексов и со всеми индексами;results/experiment_metadata.json— параметры прогона, включая фактически использованный seed;results/benchmark_summary.md— машинно сгенерированная текстовая сводка по benchmark.
results/summary_ru.md— краткое русскоязычное описание результатов;results/benchmark_table_ru.csv— русскоязычная таблица статистики;results/index_effectiveness_ru.csv— русскоязычная таблица эффективности индексов;results/load_performance_ru.csv— русскоязычная таблица загрузки данных;
charts/postgres_boxplots.pngcharts/mysql_boxplots.pngcharts/mongo_boxplots.pngcharts/postgres_run_trends.pngcharts/mysql_run_trends.pngcharts/mongo_run_trends.pngcharts/postgres_relative_effect.pngcharts/mysql_relative_effect.pngcharts/mongo_relative_effect.png
Эти файлы создаются отдельными helper-скриптами:
python scripts/build_q1_median_chart.pypython scripts/build_q1_run_times_chart.py
Результаты:
results/q1_student_id_median_times_all_dbms.csv— медианы Q1 по трем СУБД;results/q1_student_id_run_times_all_dbms.csv— все строки Q1 дляidx_student_id_only;charts/q1_student_id_median_times_all_dbms.png— столбчатый график медиан Q1;charts/q1_student_id_median_times_all_dbms_log.png— логарифмическая версия графика медиан Q1;charts/q1_student_id_run_times_with_median_subplots.png— график прогонов Q1 с линиями медианы.
explain_plans/postgres/explain_plans/mysql/explain_plans/mongo/
Файлы charts/student_activity_schema.png и charts/load_time_comparison.png больше не создаются текущими скриптами и из описания убраны.
cd .\index-perfomance-research-mainpython -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install --upgrade pip
pip install -r requirements.txtЕсли PowerShell блокирует активацию:
Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass
.\.venv\Scripts\Activate.ps1docker compose up -d
docker compose pspython scripts/run_all.pyЭта команда:
- ждет готовности сервисов;
- генерирует CSV;
- создает схемы;
- загружает данные;
- прогоняет benchmark по всем индексным конфигурациям;
- строит графики;
- измеряет влияние индексов на загрузку данных;
- формирует русскоязычные выходы.
Если нужно выполнять этапы вручную:
python scripts/wait_for_services.py
python scripts/generate_data.py --rows 1000000
python scripts/create_schema.py
python scripts/load_data.py
python scripts/check_counts.py
python scripts/benchmark.py --warmups 0 --runs 1000
python scripts/build_charts.py
python scripts/measure_load_performance.py
python scripts/build_readable_outputs.py
python scripts/build_q1_median_chart.py
python scripts/build_q1_run_times_chart.pyДля точного повтора конкретного датасета:
python scripts/generate_data.py --rows 1000000 --seed <seed>Перед тяжелым прогоном удобно проверить пайплайн на короткой серии:
python scripts/run_all.py --rows 10000 --runs 5 --skip-load-measurementТакой тест не заменяет основной эксперимент, но помогает убедиться, что код и контейнеры работают корректно.
После запуска имеет смысл проверить:
python scripts/check_counts.pyИ убедиться, что появились файлы:
results/benchmark_results.csvresults/benchmark_stats.csvresults/benchmark_medians.csvresults/index_effectiveness.csvresults/load_performance.csvresults/experiment_metadata.jsonresults/benchmark_summary.mdresults/summary_ru.mdresults/benchmark_table_ru.csvresults/index_effectiveness_ru.csvresults/load_performance_ru.csvresults/q1_student_id_median_times_all_dbms.csvresults/q1_student_id_run_times_all_dbms.csvcharts/postgres_boxplots.pngcharts/mysql_boxplots.pngcharts/mongo_boxplots.pngcharts/postgres_run_trends.pngcharts/mysql_run_trends.pngcharts/mongo_run_trends.pngcharts/postgres_relative_effect.pngcharts/mysql_relative_effect.pngcharts/mongo_relative_effect.pngcharts/q1_student_id_median_times_all_dbms.pngcharts/q1_student_id_median_times_all_dbms_log.pngcharts/q1_student_id_run_times_with_median_subplots.png
Остановить контейнеры без удаления данных:
docker compose downПолностью удалить контейнеры и volumes:
docker compose down -vПосле down -v данные в СУБД исчезнут, и загрузку нужно будет выполнять заново.