Какие основные методы оптимизации SQL-запросов ты применяешь?

Ответ

Оптимизация SQL — ключевой навык для работы с БД. Вот основные методы:

  1. Использование индексов:

    • Создание индексов для полей, используемых в WHERE, JOIN, ORDER BY, GROUP BY.
    • Анализ «медленных» запросов для выявления кандидатов на индексирование.
      -- Индекс для ускорения поиска и сортировки
      CREATE INDEX idx_orders_status_created ON orders(status, created_at DESC);
  2. Анализ плана выполнения (EXPLAIN):

    • Использование EXPLAIN или EXPLAIN ANALYZE для понимания, как СУБД выполняет запрос (выбор индексов, типы JOIN, стоимость).
  3. Оптимизация структуры запросов:

    • Замена коррелированных подзапросов на JOIN.
    • Избегание SELECT * — выборка только необходимых столбцов.
    • Использование LIMIT для пагинации и ограничения результата.
    • Корректное использование UNION / UNION ALL.
  4. Пример оптимизации «до/после»:

    -- Медленный запрос (полный перебор таблицы)
    SELECT * FROM users WHERE YEAR(created_date) = 2023;
    
    -- Оптимизированный запрос (использует индекс по created_date)
    SELECT * FROM users 
    WHERE created_date >= '2023-01-01' AND created_date < '2024-01-01';
  5. Кэширование:

    • Настройка кэша запросов на уровне СУБД.
    • Использование кэша второго уровня в Hibernate для часто читаемых, редко меняющихся данных.
  6. Нормализация/денормализация схемы:

    • В сложных случаях — анализ и возможная денормализация таблиц для уменьшения количества JOIN.

Ответ 18+ 🔞

Да ты посмотри, какие тут советы по SQL собрали, прямо как в аптеке рецепты! Ну ладно, разберём эту хуйню по полочкам, чтобы не ебать мозги потом на проде.

Первое и главное — индексы, ёпта! Это как алфавитный указатель в книге, а без него тебе всю книгу читать придётся, чтобы найти одну строчку. Ставь их на поля, которые в WHERE, JOIN и прочих ORDER BY мелькают. Смотришь на медленный запрос — сразу думаешь, на что индекс натянуть.

-- Вот смотри, сделал индекс на статус и дату — и запрос летает как угорелый
CREATE INDEX idx_orders_status_created ON orders(status, created_at DESC);

Дальше — EXPLAIN, блядь! Это как рентген для запроса. Засунул его перед своим SQL — и сразу видно, какой план выполнения СУБД придумала, какие индексы юзает, а где тупо всю таблицу сканирует. Без этого — как в жопу пальцем тыкать.

Теперь про структуру запросов. Тут народ такое вытворяет — волосы дыбом!

  • Вместо этих ебучих коррелированных подзапросов, которые для каждой строки внешнюю таблицу дергают, пиши нормальный JOIN.
  • SELECT * — это вообще пиздец, зачем тебе все колонки тащить, если нужны две? Бери только то, что надо.
  • LIMIT не забывай, особенно если пагинацию делаешь, а то выгрузишь всю базу на клиент и офигеешь.

Вот тебе живой пример, как из говна конфетку сделать:

-- Было: запрос, который ебёт всю таблицу, потому что функция YEAR() индекс похерила
SELECT * FROM users WHERE YEAR(created_date) = 2023;

-- Стало: умный диапазон, который индекс отработает как по маслу
SELECT * FROM users 
WHERE created_date >= '2023-01-01' AND created_date < '2024-01-01';

Кэширование — тоже штука полезная. Если одни и те же данные часто читаются, а меняются редко — настрой кэш в СУБД или, если через Hibernate работаешь, кэш второго уровня. Но осторожно, а то закэшируешь хуйню и потом три дня ищешь, почему данные не обновились.

И наконец, схема базы. Нормализация — это хорошо, но иногда JOIN'ов становится овердохуища, и запрос начинает ползти как черепаха. Тогда надо подумать про денормализацию — слегка нарушить святые принципы, добавить немного избыточных данных, чтобы меньше соединять таблицы. Но это уже высший пилотаж, бездумно не делай, а то получишь бардак ебаный.

Короче, SQL оптимизация — это не магия, а ремесло. Смотри на планы, думай головой, и не делай тупых вещей. И всё будет пучком, блядь!