Вы думаете, во вложенных циклах. Это то, что вы должны преодолеть при работе с реляционной базой данных (если вы не используете MySQL).
То, что вы описываете как «1 + n», является вложенным циклом: вы сканируете одну таблицу, и для каждой найденной строки вы сканируете другую таблицу.
Как написан ваш SQL-запрос, у PostgreSQL нет другого выбора, кроме как выполнить вложенный цикл.
Это хорошо, если во внешней таблице (film
в вашем примере) есть несколько строк. Производительность быстро ухудшается, когда внешний стол становится больше.
Помимо вложенных циклов, PostgreSQL имеет две другие стратегии соединения:
Хеш-соединение: Внутренняя связь сканируется, и создается хеш-структура, где хеш-ключ является ключом соединения. Затем сканируется внешнее отношение и проверяется хэш для каждой найденной строки.
Думайте об этом как о неком хэш-соединении, но с внутренней стороны у вас есть эффективная структура данных в памяти.
Объединение слиянием: Обе таблицы сортируются по ключу объединения и объединяются путем одновременного сканирования результатов.
Рекомендуется написать запрос без & ldquo; коррелированных подзапросов & rdquo; чтобы PostgreSQL мог выбрать оптимальную стратегию объединения:
SELECT film_id, f.title, array_agg(a.first_name)
FROM film f
LEFT JOIN film_actor fa USING (film_id)
LEFT JOIN actor a USING (actor_id)
GROUP BY f.title
ORDER BY f.title;
Левое внешнее объединение используется для получения результата, даже если в фильме нет актеров.