Вложенные INNER JOIN против INNER JOIN vs. WHERE: правильность, производительность, ясность для конкретного случая (не типичная проблема JOIN vs WHERE)
Я изучаю внутренние соединения, и я старый человек WHERE SQL-92. Я хотел бы знать последствия и понять, как это работает. Так что это всего лишь теоретический вопрос о соединениях SQL.
Это...
SELECT * FROM -- Query 1
tbl1
INNER JOIN (
tbl2
INNER JOIN (
tbl3 INNER JOIN tbl4 ON tbl3.Col1 = tbl4.Col1
)
ON tbl2.col1 = tbl3.col2
)
ON tbl1.col1 = tbl3.col3
... так же, как это?
SELECT * FROM -- Query 2
tbl3
INNER JOIN tbl4 ON tbl3.col1 = tbl4.col1
INNER JOIN tbl2 ON tbl2.col1 = tbl3.col2
INNER JOIN tbl1 ON tbl1.col1 = tbl3.col3
... или это (не отсортировано по логическому разрешению)?
SELECT * FROM -- Query 3
tbl3
INNER JOIN tbl1 ON tbl1.col1 = tbl3.col3
INNER JOIN tbl2 ON tbl2.col1 = tbl3.col2
INNER JOIN tbl4 ON tbl3.col1 = tbl4.col1
.. или это (ссылка node изменена; см. таблицу, на которую ссылаются до ее цитирования, но декартово произведение должно быть одинаковым)
SELECT * FROM -- Query 4
tbl4
INNER JOIN tbl1 ON tbl1.col1 = tbl3.col3
INNER JOIN tbl2 ON tbl2.col1 = tbl3.col2
INNER JOIN tbl3 ON tbl4.col1 = tbl3.col1
.. или это?
SELECT * FROM -- Query 5
tbl1,tbl2,tbl3,tbl4
WHERE
tbl3.col1 = tbl4.col1
tbl2.col1 = tbl3.col2
tbl1.col1 = tbl3.col3
... с эстетической, синтаксической, лучшей практики и функциональных точек зрения?
Это очень открытый вопрос, но я думаю, что сообщество довольно интересно проливать свет!
Ответы
Ответ 1
Все двигатели базы данных, с которыми я тесно работал (это SQL Server
, Oracle
, PostgreSQL
, MySQL
, Sybase
, SQLite
, Informix
и Firebird
) будут оптимизировать это тот же план.
Четвертый запрос, однако, не будет анализировать на всех машинах (вы не можете ссылаться на таблицу в предложении ON
до того, как она была использована в предложении JOIN
)
MySQL
предлагает предложение STRAIGHT_JOIN
, которое влияет на порядок соединения, используемый в плане.
В Oracle
есть подсказка /*+ ORDERED */
, а в SQL Server
имеется аналогичный намек FORCE ORDER
. Если запрос использует эти подсказки, на заказ плана будет также влиять порядок соединения.
Ответ 2
С точки зрения правильности они, вероятно, равны. С точки зрения производительности, это зависит от СУБД (я могу говорить только для SQL Server, где все варианты будут давать один и тот же план выполнения).
Ответ 3
В Sybase у них будет один и тот же план выполнения!
Оптимизатор запросов достаточно умен, чтобы построить один и тот же план выполнения для всех из них:)
Он может внутренне изменить запрос, чтобы сначала выбрать наименьшую таблицу и сделать внутренние соединения с этим.
Regardind использует внутреннее соединение или вложенное соединение (последнее), я предпочитаю первый. Это более читаемо, чтобы иметь внутренние соединения с соединениями между таблицами, а затем, если необходимо, предложение where с ограничениями (в вашем примере у вас нет этих ограничений).