главная/Как derived tables могут ускорить SQL в разы
Derived table

Как derived tables могут ускорить SQL в разы

Недавно оптимизировал огромный квери в проекте.
На первый взгляд всё выглядело нормально: запрос считал количество проданных билетов и оставшиеся места для каждого события.

Но под капотом использовались correlated subqueries — подзапросы, которые выполняются для каждой строки результата.

При большом количестве событий это превращается в сотни или тысячи повторных вычислений.

Решение оказалось довольно простым: заменить correlated subqueries на derived tables и один JOIN.

Это превращает:

N строк × подзапрос

в

1 агрегация + 1 JOIN

Упрощённый пример.

SELECT
    e.*,
    GREATEST(
        0,
        e.total_tickets
        - (
            SELECT COUNT(*)
            FROM order_tickets ot
            WHERE ot.event_id = e.id
              AND ot.status = 'active'
        )
    ) AS remaining_tickets
FROM events e
ORDER BY remaining_tickets DESC;

Для каждого события база выполняет:

COUNT(*) FROM order_tickets WHERE event_id = e.id

Фактически для каждого эвента запускай саб квери. Даже с индексами это всё равно повторяющаяся работа.

Derived table

Derived table — это подзапрос, который используется как временная таблица внутри SQL-запроса.

SELECT
    e.*,
    GREATEST(
        0,
        e.total_tickets - COALESCE(sold_agg.sold_count, 0)
    ) AS remaining_tickets
FROM events e
LEFT JOIN (
    SELECT
        event_id,
        COUNT(*) AS sold_count
    FROM order_tickets
    WHERE status = 'active'
    GROUP BY event_id
) sold_agg
    ON sold_agg.event_id = e.id
ORDER BY remaining_tickets DESC;

Теперь база: Один раз агрегирует продажи

event_id → sold_count

Джойнит результат к событиям.

То есть вместо: N × subquery мы получаем 1 aggregation + 1 join

Она существует только во время выполнения запроса, но позволяет:

  • заранее агрегировать данные
  • уменьшить повторные вычисления
  • упростить сложные JOIN-операции