Вложенные 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 с ограничениями (в вашем примере у вас нет этих ограничений).