Как оптимизировать производительность медленного SQL-запроса?

«Как оптимизировать производительность медленного SQL-запроса?» — вопрос из категории Базы данных, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Оптимизация запроса — системный процесс. Вот основные направления:

1. Анализ плана выполнения: Используйте EXPLAIN (или EXPLAIN ANALYZE) чтобы понять, как СУБД выполняет запрос, и найти «узкие места» (например, полные сканирования таблиц — Seq Scan).

2. Добавление индексов: Создавайте индексы для столбцов в условиях WHERE, JOIN, ORDER BY.

   -- Медленный запрос без индекса
   SELECT * FROM orders WHERE customer_id = 123 AND status = 'SHIPPED';

   -- Создание составного индекса
   CREATE INDEX idx_orders_customer_status ON orders(customer_id, status);

3. Рефакторинг запроса:

  • Избегайте SELECT * — выбирайте только нужные столбцы.
  • Заменяйте коррелированные подзапросы на JOIN.
  • Используйте LIMIT для пагинации.
  • Кэшируйте результаты частых и тяжелых запросов (на уровне приложения или СУБД).

4. Оптимизация структуры данных:

  • Партиционирование больших таблиц по диапазонам или хэшу.
  • Денормализация — осознанное дублирование данных для исключения дорогих JOIN.
  • Пересмотр типов данных (использование более эффективных, например, INT вместо VARCHAR для ID).

5. Настройка СУБД: Увеличьте параметры, связанные с памятью (например, shared_buffers в PostgreSQL, innodb_buffer_pool_size в MySQL), чтобы больше данных хранилось в оперативной памяти.