Что происходит при запросе SELECT * FROM table1, table2 без JOIN
Что проверяют
Знаете ли вы, что запятая в списке таблиц это старый синтаксис перекрёстного соединения, и понимаете ли, откуда в приложении берутся раздутые выборки. У Java-разработчика вопрос почти всегда выводит на Hibernate.
Как отвечать
Запятая между таблицами даёт декартово произведение, полный эквивалент CROSS JOIN: каждая строка первой таблицы склеивается с каждой строкой второй. Из тысячи и тысячи строк получается миллион, и такая выборка легко кладёт приложение по памяти, потому что результат разбирается на его стороне.
Дальше важная оговорка, которую обычно и ждут. Как только появляется условие связи, запрос перестаёт быть произведением по сути:
select * from orders o, customers c
where o.customer_id = c.idЭто обычное внутреннее соединение, записанное старым способом. Планировщик произведение не материализует, он выберет тот же алгоритм соединения, что и для явного JOIN. Разница в читаемости и в риске: потерянное условие превращает запрос в произведение молча, а в записи через JOIN ... ON условие стоит рядом с таблицей и потеряться не может. Внешние соединения запятой не выражаются вовсе.
Для Java стоит добавить, что то же самое случается в JPQL при перечислении сущностей через запятую и при выборке двух коллекций сразу через join fetch: строки перемножаются, и вместо десятка объектов приезжает их произведение.
Где спотыкаются
Говорят, что такой запрос вернёт объединение таблиц. Объединение это UNION, оно складывает строки по вертикали и требует совместимых колонок, а запятая перемножает строки по горизонтали.
Второе: пишут выборку со звёздочкой и читают результат по имени колонки. У двух таблиц одноимённые поля вроде id встречаются дважды, и драйвер отдаст первое попавшееся, а не то, которое имелось в виду. Колонки надо перечислять явно и давать им псевдонимы.
Третье: оценивают опасность по числу строк на своей машине. На тестовых данных произведение незаметно, а на боевых тот же запрос выедает память и у базы, и у приложения, поэтому смотреть план запроса надо на объёмах, похожих на реальные.