Является NATURAL JOIN лучше, чем SELECT FROM WHERE с точки зрения производительности?

Возможный дубликат:
Внутреннее соединение vs Где

Сегодня я вошел в дискуссию с моим менеджером проектов о продуктах Cartesian. Он говорит, что "естественное соединение" как-то намного лучше, чем использование "выбирать из того, где", потому что позже заставить движок db внутренне выполнять декартовский продукт, но первый использует другой подход, который предотвращает это. Насколько я знаю, синтаксис естественного соединения ничем не отличается от "выбирать из того, где" с точки зрения производительности или значения, я имею в виду, что вы можете использовать либо по своему вкусу.

SELECT * FROM table1,table2 WHERE table1.id=table2.id
SELECT * FROM table1 NATURAL JOIN table2

просьба подробно рассказать о первом запросе, вызывающем декартово произведение, а второе - как-то более умном

Ответ 1

Правильный путь должен быть явным с фильтрами и объединениями разделены

SELECT * FROM table1 JOIN table2 ON table1.id = table2.id

ПРИРОДНЫЕ СОЕДИНЕНИЯ могут быть легкими и "чистыми", но, скорее всего, совершенно непредсказуемыми...

Изменить, май 2012 г.

Принятый ответ для дубликата фактически не отвечает NATURAL JOIN.
Эти ссылки обсуждаются более подробно.

ТЛ; дг

Производительность не является проблемой: но ваши запросы должны быть надежными и предсказуемыми, что, естественно, нет ПРИРОДНЫЙ ПРИСОЕДИНЯЙТЕСЬ.

"ПРИСОЕДИНЯЙТЕСЬ В ГДЕ", иначе подразумеваемый JOIN, так называемый "картезианский", также плох в соответствии с этими ссылками (то же самое относится и к Oracle, а также к SQL Server)

Ответ 2

Это зависит.

Естественное соединение связывает все столбцы в двух таблицах с тем же именем. Если только два столбца в таблицах 1 и 2 с таким же именем являются идентификаторами, то два запроса должны оцениваться одинаково оптимизатором; с другой стороны, если в двух таблицах имеется более двух столбцов с одинаковым именем (или вообще нет), выполняется совершенно другой запрос.

В любом случае декартово произведение почти неизменно (я хочу сказать всегда) выполняю хуже, чем любой другой тип соединения, поскольку он соединяет каждую запись одной таблицы с каждой записью другой таблицы.

Насколько хорош ваш менеджер, чтобы отличить его gluteus maximus от верхнего конца его локтевой кости?

Ответ 3

По производительности, нет никакой разницы. Его обсуждали снова и снова. Googling для "join синтаксис oracle vs where" приводит к нескольким хорошим статьям, в том числе и на этом сайте, на который ссылается Александр.

Однако будьте осторожны при использовании NATURAL JOIN. Он будет собирать общие столбцы, такие как createate или createuser, или такие, что вам обычно действительно не нужно присоединяться и может вызвать проблемы. Я настоятельно рекомендую против NATURAL JOIN в производстве... просто используйте INNER JOIN и укажите столбцы.

Даже Том согласен.

Ответ 4

Прежде всего следует отметить, что оптимизаторы баз данных интерпретируют синтаксис по-своему. Очевидно, что каждый продукт меняется, но я был бы откровенно удивлен, если какая-либо СУБД оштрафовала за то, что является наиболее распространенным механизмом для объединения таблиц.

Что касается терминологии, то это перекрестное объединение, которое порождает декартово произведение. Это отличается от внутреннего соединения и генерирует другой набор результатов.

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

Ответ 5

Я бы не использовал ни синтаксис. Ваш запрос указывает на внутреннее соединение, я бы использовал явный синтаксис для этого. Вы не должны использовать подразумеваемые объединения когда-либо, они подвержены неверному истолкованию (было ли случайное крестовое соединение или вы хотели это сделать?) И случайные кросс-соединения. Вы бы использовали код С#, который был заменен на 18 лет агао с лучшим синтаксисом (ну, на самом деле С# не существует 18 лет назад, но я думаю, вы понимаете, что я говорю)? Тогда почему вы используете устаревший код SQL?

Не только подразумевается объединение проблемы для обслуживания, но это может быть большой проблемой, если вы попытаетесь использовать подразумеваемый синтаксис соединения для внешних соединений, поскольку это не работает корректно в некоторых базах данных и также устарело, по крайней мере, в одной базе данных, SQL Server, я знаю. И если вам нужна фильтрация в таблице в левом соединении, вы не можете сделать это с подразумеваемым синтаксисом вообще, потому что он преобразует его в innner join.

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

Я никогда в 30-летнем возрасте от запросов к базам данных не видел необходимости писать естественное соединение и должен был искать то, что было, поэтому использование этого не более понятно, чем подразумеваемое соединение.