Имеет ли значение порядок таблиц в соединении, когда используются соединения LEFT (внешние)? - PullRequest
7 голосов
/ 16 февраля 2011

Я хотел бы подтвердить, что запрос SQL

SELECT ....
  FROM apples,
       oranges
       LEFT JOIN kiwis ON kiwis.orange_id = oranges.id,
       bananas
 WHERE ....

точно эквивалентен другим перестановкам в подпункте FROM, например

SELECT ....
  FROM oranges
       LEFT JOIN kiwis ON kiwis.orange_id = oranges.id,
       bananas,
       apples
 WHERE ....

или

SELECT ....
  FROM bananas,
       apples,
       oranges
       LEFT JOIN kiwis ON kiwis.orange_id = oranges.id
 WHERE ....

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

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

Ответы [ 3 ]

15 голосов
/ 16 февраля 2011

Это то же самое, но это чертовски неоднозначно с неявными CROSS JOIN. Используйте явные СОЕДИНЕНИЯ.

Если вы присоединяетесь к предложению WHERE, тогда результаты могут отличаться, потому что объединения и фильтры перепутаны.

SELECT ....
  FROM apples a
       JOIN
       bananas b ON ...
       JOIN 
       oranges o ON ...
       LEFT JOIN
       kiwis k ON k.orange_id = o.id
 WHERE (filters only)

Примечания:

  • ВНУТРЕННИЕ СОЕДИНЕНИЯ и КРЕСТНЫЕ СОЕДИНЕНИЯ являются коммутативными и ассоциативными: порядок обычно не имеет значения.
  • ВНЕШНИХ СОЕДИНЕНИЙ нет, которые вы определили
  • SQL декларативен: вы говорите оптимизатору, что вы хотите, а не как это сделать. Это устраняет соображения, связанные с порядком присоединения (с учетом предыдущих 2 пунктов)
1 голос
/ 16 февраля 2011

Ситуация обобщена на Управление планировщиком с помощью явных предложений JOIN . Внешние соединения не переупорядочиваются, внутренние могут быть. И вы можете навязать определенный порядок оптимизатора, опустив * join_collapse_limit * перед выполнением запроса, и просто расположив все в том порядке, в котором вы хотите. Вот как вы «намекаете» на базу данных в этой области.

Как правило, вы хотите использовать EXPLAIN для подтверждения того, какой заказ вы получаете, и это иногда можно использовать для визуального подтверждения того, что два запроса получают один и тот же план.

0 голосов
/ 16 февраля 2011

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

Поставщик базы данных совершил бы коммерческое самоубийство, если бы его оптимизировали в порядке, в котором вы лично указали SQL в своем запросе.

...