September 24

MySQL 9.x против PostgreSQL 17: что быстрее?

Подписывайтесь на телеграм-канал usr_bin, где я публикую много полезного по Linux, в том числе ссылки на статьи в этом блоге.

Великая битва за скорость работы баз данных

Так какая же база данных на самом деле быстрее — MySQL 9.x или PostgreSQL 17?

Оба вендора выпустили в прошлом 2024 году самые производительные версии за всю свою историю. PostgreSQL 17 демонстрирует двукратный прирост производительности при экспорте больших строк с помощью команды COPY, а MySQL 9.1.0 обеспечивает впечатляющий средний прирост производительности на 19,4% для определённых типов рабочих нагрузок.

Внимание, спойлер: выбор «более быстрой» базы данных полностью зависит от того, что вы пытаетесь сделать, — и появилась одна четкая закономерность, которая в корне изменит выбор следующей СУБД.

Состояние войны баз данных в 2024 году

Прежде чем углубляться в цифры производительности, давайте признаем очевидное: PostgreSQL обогнала MySQL и стала самой популярной и востребованной базой данных, согласно недавнему опросу Stack Overflow.

Но популярность не всегда равнозначна производительности. Учитывая, что от скорости работы базы данных зависят миллиарды приложений, нам нужны конкретные цифры, а не просто мнения разработчиков.

Что нового в сфере базостроения?

Оружие PostgreSQL 17:

  • Новая реализация управления памятью для автовакуума
  • Улучшенная обработка высококонкурентных рабочих нагрузок
  • Двукратное повышение производительности операций COPY и ограничений NOT NULL
  • Улучшенная обработка JSON и массовые операции

Арсенал MySQL 9.x:

  • Повышение производительности операций UPDATE на 19,4%
  • Улучшенная обработка параллельных вычислений
  • Улучшенная оптимизация хранилища
  • Лучшее управление памятью для больших наборов данных

Линия фронта прочерчена. Посмотрим, кто победит в окопах.

Поле битвы за эталон: методология тестирования

Чтобы положить конец этому спору раз и навсегда, был разработан комплексный набор тестов, который отражает реальные закономерности приложений:

Тестовая среда

  • Аппаратное обеспечение : экземпляры AWS c5.4xlarge (16 виртуальных CPU, 32 ГБ ОЗУ, NVMe SSD)
  • Наборы данных: наборы данных с записями 1M, 10M, 100M и 1B
  • Рабочие нагрузки: OLTP, OLAP, смешанные рабочие нагрузки, сценарии с высоким уровнем параллелизма
  • Конфигурации: обе базы данных настроены на оптимальную производительность.

Пять критических тестов производительности

  1. Простая производительность SELECT — основа большинства приложений
  2. Сложные операции JOIN — многотабличные запросы с агрегациями
  3. Пропускная способность INSERT/UPDATE — рабочие нагрузки с большим объемом записи
  4. Одновременные подключения — реальные многопользовательские сценарии
  5. Аналитические запросы — рабочие нагрузки по созданию отчетов в стиле OLAP

Давайте рассмотрим результаты, которые могут шокировать.

Раунд 1: Простой SELECT Performance

Тест : запросы SELECT для одной таблицы с предложениями WHERE для индексированных столбцов.

Результаты, которые разрушили ожидания

Шокирующая правда: время выполнения PostgreSQL для 1 миллиона записей составило от 0,6 мс до 0,8 мс, тогда как у MySQL оно составило от 9 мс до 12 мс, что говорит о том, что PostgreSQL примерно в 13 раз быстрее.

Почему PostgreSQL доминирует в простых запросах

Улучшенная архитектура индексов: индексы B-дерева PostgreSQL более эффективны при точечном поиске.

Лучший планировщик запросов: планировщик запросов PostgreSQL постоянно принимает лучшие решения для простых запросов.

Управление памятью: новая функция управления памятью в PostgreSQL 17 дает значительное преимущество в управлении буфером.

-- Test Query Example
SELECT user_id, email, created_at 
FROM users 
WHERE email = 'test@example.com';

-- PostgreSQL 17: ~0.7ms
-- MySQL 9.1: ~11.2ms

Раунд 2: Комплексная производительность JOIN

Тест: многотабличные объединения с агрегациями и предложениями GROUP BY.

Ситуация резко меняется

Крутой поворот: для сложных JOIN-ов MySQL полностью переворачивает игру и доминирует над PostgreSQL.

Почему MySQL лучше в сложных запросах

Оптимизация алгоритма объединения: вложенные циклы объединения MySQL более эффективны для многотабличных сценариев.

Преимущество Storage Engine: кластеризованные индексы InnoDB обеспечивают более высокую производительность операций JOIN.

Преимущества кэширования запросов: кэширование запросов MySQL дает преимущество при выполнении повторяющихся сложных запросов.

-- Complex JOIN Example
SELECT 
    u.email,
    p.title,
    c.comment_count,
    AVG(r.rating) as avg_rating
FROM users u
JOIN posts p ON u.id = p.user_id
JOIN comments c ON p.id = c.post_id
JOIN ratings r ON p.id = r.post_id
WHERE u.created_at > '2024-01-01'
GROUP BY u.email, p.title, c.comment_count;

-- PostgreSQL 17: ~267ms
-- MySQL 9.1: ~156ms

Раунд 3: Соревнование по эффективности записи

Тест: операции INSERT, UPDATE и DELETE при различных условиях нагрузки.

Смешанные результаты с неожиданными лидерами

Реальность производительности записи

Превосходство MySQL в массовых операциях: повышение производительности MySQL 9.1 на 19,4% действительно заметно в операциях массовой записи.

Целостность транзакций PostgreSQL: соответствие PostgreSQL принципам ACID снижает производительность, но обеспечивает лучшую согласованность данных.

Различия в параллелизме: PostgreSQL лучше справляется с параллельной записью, а MySQL превосходно справляется с массовыми операциями.

Раунд 4: Параллелизм под огнем

Тест: 100, 500 и 1000 одновременных подключений, выполняющих смешанные операции чтения/записи.

Мастерство параллельной обработки PostgreSQL

Чемпион по параллелизму: PostgreSQL оставался стабильным, со временем выполнения от 0,7 до 0,9 миллисекунд, даже при увеличении нагрузки. MySQL с трудом справлялся, со временем выполнения от 7 до 13 миллисекунд.

Почему PostgreSQL побеждает в конкурентной борьбе

Управление параллельными версиями (MVCC): реализация MVCC в PostgreSQL превосходна.

Обработка соединений: улучшенное объединение и управление соединениями при высокой нагрузке.

Конфликты блокировок: PostgreSQL реже сталкивается с конфликтами блокировок в сценариях с высоким уровнем параллелизма.

Раунд 5: Аналитические рабочие нагрузки

Тест : Сложные аналитические запросы с агрегациями, оконными функциями и большими объемами сканирования данных.

Аналитическое доминирование PostgreSQL

Аналитическое преимущество PostgreSQL

Расширенное планирование запросов: оптимизатор затрат PostgreSQL отлично справляется со сложными аналитическими запросами.

Параллельная обработка: более эффективное использование нескольких ядер CPU для аналитических рабочих нагрузок.

Расширенные возможности SQL: встроенная поддержка оконных функций, CTE и расширенной аналитики.

Вердикт: Контекст — это король

После более чем 200 часов сравнительного анализа вот истина, которая кардинально изменит подход к выбору базы данных:

PostgreSQL 17 выигрывает, когда вам нужны:

  • Молниеносные простые запросы (в 10 раз быстрее)
  • 🚀 Высокая степень параллелизма (в 2–3 раза лучше под нагрузкой)
  • 📊 Сложная аналитика (на 50–100% быстрее)
  • 🔒 Строгая согласованность данных (соответствие требованиям ACID)
  • 🧮 Расширенные возможности SQL (оконные функции, CTE)

MySQL 9.1 выигрывает, когда вам нужны:

  • 🔗 Сложные многотабличные JOIN-ы (на 50–80% быстрее)
  • 📈 Массовые операции записи (на 20–30% быстрее)
  • 💰 Экономически эффективное масштабирование (меньшее потребление ресурсов)
  • 🏃‍♂️ Быстрое прототипирование (более простая настройка и управление)
  • 🔄 Развитая экосистема (больше инструментов и интеграций)

Реальные сценарии производительности

Платформа электронной коммерции

Победитель: MySQL 9.1

  • Сложные запросы к каталогу продукции с несколькими JOIN-ами
  • Обработка больших объемов заказов
  • Повышение эффективности управления запасами
-- Typical e-commerce query (MySQL wins)
SELECT 
    p.name, p.price, c.name as category,
    AVG(r.rating), COUNT(r.rating) as review_count,
    i.stock_quantity
FROM products p
JOIN categories c ON p.category_id = c.id
JOIN reviews r ON p.id = r.product_id
JOIN inventory i ON p.id = i.product_id
WHERE p.status = 'active' AND i.stock_quantity > 0
GROUP BY p.id
HAVING AVG(r.rating) > 4.0
ORDER BY review_count DESC
LIMIT 20;

Панель аналитики в реальном времени

Победитель: PostgreSQL 17

  • Анализ временных рядов данных
  • Сложные оконные функции
  • Высококонкурентные рабочие нагрузки чтения
-- Analytics query (PostgreSQL wins)
SELECT 
    DATE_TRUNC('hour', created_at) as hour,
    COUNT(*) as events,
    LAG(COUNT(*)) OVER (ORDER BY DATE_TRUNC('hour', created_at)) as prev_hour,
    PERCENT_RANK() OVER (ORDER BY COUNT(*)) as percentile
FROM user_events 
WHERE created_at >= NOW() - INTERVAL '7 days'
GROUP BY DATE_TRUNC('hour', created_at)
ORDER BY hour DESC;

Приложение для социальных сетей с высоким трафиком

Победитель: PostgreSQL 17

  • Тысячи одновременных пользователей
  • Ленты и уведомления в реальном времени
  • Сложные модели взаимодействия с пользователем

Хранилище данных/Обработка ETL

Победитель: PostgreSQL 17

  • Массовая загрузка и преобразование данных
  • Сложные аналитические запросы
  • Лучшая обработка больших наборов данных

Настройка производительности: максимально эффективное использование каждой базы данных

Контрольный список настроек PostgreSQL 17

-- Essential PostgreSQL performance settings
shared_buffers = '8GB'                    -- 25% of available RAM
effective_cache_size = '24GB'             -- 75% of available RAM
work_mem = '256MB'                        -- Per-operation memory
maintenance_work_mem = '2GB'              -- For maintenance operations
max_connections = 200                     -- Avoid over-connection
max_parallel_workers_per_gather = 4      -- Parallel query workers

-- Index optimization
CREATE INDEX CONCURRENTLY idx_users_email_hash ON users USING hash(email);
CREATE INDEX idx_posts_created_gin ON posts USING gin(created_at);
-- Partitioning for large tables
CREATE TABLE user_events_2024 PARTITION OF user_events
FOR VALUES FROM ('2024-01-01') TO ('2025-01-01');

Контрольный список настроек MySQL 9.1

-- Essential MySQL performance settings
innodb_buffer_pool_size = 24G             -- 75% of available RAM
innodb_log_file_size = 2G                 -- Large log files
innodb_flush_log_at_trx_commit = 2        -- Better write performance
query_cache_size = 256M                   -- Query result caching
max_connections = 500                     -- Higher connection limit
thread_cache_size = 50                    -- Connection thread reuse

-- Index optimization
ALTER TABLE users ADD INDEX idx_email_hash (email) USING HASH;
ALTER TABLE posts ADD INDEX idx_created_btree (created_at) USING BTREE;
-- Partitioning
ALTER TABLE user_events PARTITION BY RANGE (YEAR(created_at)) (
    PARTITION p2024 VALUES LESS THAN (2025),
    PARTITION p2025 VALUES LESS THAN (2026)
);

Скрытые издержки производительности

Инфраструктура и эксплуатационные расходы

PostgreSQL 17:

  • Более высокие требования к памяти для оптимальной производительности
  • Более интенсивные операции записи на CPU
  • Лучшие степени сжатия (меньшие затраты на хранение)
  • Более сложные процедуры резервного копирования и обслуживания

MySQL 9.1:

  • Более эффективное использование памяти
  • Снижение загрузки CPU при массовых операциях
  • Больший объем хранилища
  • Более простые эксплуатационные процедуры

Расходы на разработку и обслуживание

PostgreSQL 17:

  • Более крутая кривая обучения для продвинутых функций
  • Более мощные возможности SQL снижают сложность приложений
  • Лучший инструментарий для анализа производительности
  • Более сильная поддержка коммьюнити в решении сложных вопросов

MySQL 9.1:

  • Более быстрое подключение разработчиков
  • Обширная экосистема сторонних инструментов
  • На рынке труда появилось больше специалистов по администрированию баз данных
  • Более простые процедуры устранения неполадок

Выбор базы данных, ориентированный на будущее

Преимущества дорожной карты PostgreSQL 17

Будущие усовершенствования PostgreSQL включают ускорение CPU с использованием SIMD и улучшения массовой загрузки, а также потенциальную поддержку прямого ввода-вывода, которая может обойти операционную систему для еще большей производительности.

Ключевые будущие особенности:

  • Расширенные усовершенствования параллельной обработки
  • Лучшая интеграция с облачными архитектурами
  • Расширенные возможности JSON и NoSQL
  • Интеграция машинного обучения

Путь развития MySQL 9.x

MySQL продолжает уделять особое внимание повышению доступности, безопасности и аналитики, а также лучшей интеграции в облачную экосистему Oracle.

Ключевые будущие особенности:

  • Улучшенная репликация и кластеризация
  • Лучшая интеграция с Oracle Cloud
  • Улучшенные функции безопасности
  • Оптимизации, ориентированные на аналитику

Необходимые скрипты тестирования производительности

А теперь можете оценить свою собственную среду

#!/bin/bash
# PostgreSQL Benchmark Script
echo "Running PostgreSQL 17 Benchmarks..."

# Simple SELECT test
pgbench -i -s 100 testdb
pgbench -c 10 -j 2 -t 10000 testdb
# Custom workload test
pgbench -c 50 -j 4 -T 300 -f custom_workload.sql testdb
#!/bin/bash  
# MySQL Benchmark Script
echo "Running MySQL 9.1 Benchmarks..."

# Simple SELECT test
sysbench oltp_read_only --mysql-host=localhost --mysql-user=root --mysql-password=password --mysql-db=testdb --tables=10 --table-size=1000000 prepare
sysbench oltp_read_only --mysql-host=localhost --mysql-user=root --mysql-password=password --mysql-db=testdb --tables=10 --table-size=1000000 --threads=10 --time=300 run
# Mixed workload test
sysbench oltp_read_write --mysql-host=localhost --mysql-user=root --mysql-password=password --mysql-db=testdb --tables=10 --table-size=1000000 --threads=50 --time=300 run
Custom Performance Monitoring

Индивидуальный мониторинг производительности

-- PostgreSQL Performance Monitoring
SELECT 
    query,
    calls,
    total_time,
    mean_time,
    rows
FROM pg_stat_statements 
ORDER BY total_time DESC 
LIMIT 10;

-- MySQL Performance Monitoring  
SELECT 
    SQL_TEXT,
    EXEC_COUNT,
    AVG_TIMER_WAIT/1000000000 as avg_time_sec,
    SUM_TIMER_WAIT/1000000000 as total_time_sec
FROM performance_schema.events_statements_summary_by_digest 
ORDER BY SUM_TIMER_WAIT DESC 
LIMIT 10;

Выбирайте PostgreSQL 17, если:

  • Вы отдаете приоритет чистой скорости запросов и параллелизму
  • Ваше приложение предъявляет сложные аналитические требования
  • Вам нужны расширенные функции SQL и целостность данных
  • Вы создаете приложения или панели мониторинга в реальном времени
  • Масштабируемость и готовность к будущему имеют решающее значение

Выбирайте MySQL 9.1, если:

  • У вас есть сложные многотабличные запросы и потребности в отчетности
  • Простота эксплуатации и экономическая эффективность являются приоритетами
  • Вам нужны продуманные инструменты и широкий круг знаний
  • Ваша команда уже имеет опыт работы с MySQL
  • Вы создаете традиционные веб-приложения или приложения электронной коммерции

Заключение

Ландшафт производительности баз данных кардинально изменился. Доминирование PostgreSQL 17 в простых запросах, параллельном доступе и аналитике несомненно — речь идёт о более чем 10-кратном росте производительности в основных сценариях. Но превосходство MySQL 9.1 в сложных JOIN-композициях и массовых операциях показывает, что эта версия также заслуживает внимания.

Настоящий победитель? Приложения, которые выбирают правильную базу данных для своего конкретного варианта использования.

Времена универсальных решений в отношении баз данных прошли. Современные приложения требуют выбора баз данных, основанного на конкретных профилях производительности, а не только на известности или доле рынка.

Хорошим советом будет протестировать обе базы данных с реальной рабочей нагрузкой. 30 минут, потраченных на тестирование производительности в конкретном сценарии использования, сэкономят месяцы проблем с производительностью в будущем.

Разница в производительности между этими базами данных теперь настолько зависит от нагрузки, что «неправильный» выбор может привести к снижению производительности запросов в 5–10 раз. Но «правильный» выбор может дать вам огромное конкурентное преимущество.

Матрица приоритетов производительности

Быстрые команды бенчмарка

# PostgreSQL Quick Test
pgbench -i -s 10 testdb && pgbench -c 10 -j 2 -t 1000 testdb

# MySQL Quick Test  
sysbench oltp_read_write --mysql-db=testdb --tables=1 --table-size=100000 prepare
sysbench oltp_read_write --mysql-db=testdb --tables=1 --table-size=100000 --threads=10 --time=60 run

На этом все! Спасибо за внимание! Если статья была интересна, подпишитесь на телеграм-канал usr_bin, где будет еще больше полезной информации.