Внутреннее соединение против Где - PullRequest
243 голосов
/ 23 сентября 2008

Есть ли разница в производительности (в оракуле) между

Select * from Table1 T1 
Inner Join Table2 T2 On T1.ID = T2.ID

И

Select * from Table1 T1, Table2 T2 
Where T1.ID = T2.ID

Ответы [ 18 ]

188 голосов
/ 10 декабря 2008

Нет! Тот же план выполнения, посмотрите на эти две таблицы:

CREATE TABLE table1 (
  id INT,
  name VARCHAR(20)
);

CREATE TABLE table2 (
  id INT,
  name VARCHAR(20)
);

План выполнения запроса с использованием внутреннего соединения:

-- with inner join

EXPLAIN PLAN FOR
SELECT * FROM table1 t1
INNER JOIN table2 t2 ON t1.id = t2.id;

SELECT *
FROM TABLE (DBMS_XPLAN.DISPLAY);

-- 0 select statement
-- 1 hash join (access("T1"."ID"="T2"."ID"))
-- 2 table access full table1
-- 3 table access full table2

И план выполнения для запроса с использованием предложения WHERE.

-- with where clause

EXPLAIN PLAN FOR
SELECT * FROM table1 t1, table2 t2
WHERE t1.id = t2.id;

SELECT *
FROM TABLE (DBMS_XPLAN.DISPLAY);

-- 0 select statement
-- 1 hash join (access("T1"."ID"="T2"."ID"))
-- 2 table access full table1
-- 3 table access full table2
65 голосов
/ 23 сентября 2008

Если оптимизатор запросов делает свою работу правильно, между этими запросами не должно быть никакой разницы. Это всего лишь два способа указать один и тот же желаемый результат.

59 голосов
/ 23 сентября 2008

Они должны быть точно такими же. Однако, как практика кодирования, я бы предпочел увидеть Join. Он четко формулирует ваше намерение,

26 голосов
/ 23 сентября 2008

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

Нет разницы в скорости ( Я только что проверил ), и план выполнения такой же.

15 голосов
/ 23 сентября 2008

Я не знаю об Oracle, но я знаю, что старый синтаксис устарел в SQL Server и со временем исчезнет. Прежде чем использовать этот старый синтаксис в новом запросе, я проверю, что Oracle планирует с ним делать.

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

И опять же, я не знаю Oracle конкретно, но я знаю, что версия SQL Server старого стиля левого объединения имеет недостатки даже в SQL Server 2000 и дает противоречивые результаты (иногда левое соединение, иногда перекрестное соединение), поэтому никогда не должен использоваться. Надеюсь, Oracle не сталкивается с той же проблемой, но, конечно, левые и правые объединения могут быть намного сложнее правильно выразить в старом синтаксисе.

Кроме того, по моему опыту (и, конечно, это сугубо личное мнение, у вас может быть другой опыт), разработчики, использующие стандартные объединения ANSII, как правило, лучше понимают, что такое объединение и что оно означает в условия получения данных из базы данных. Я полагаю, что это потому, что большинство людей с хорошим пониманием базы данных, как правило, пишут более сложные запросы, и мне кажется, что их легче поддерживать с помощью стандарта ANSII, чем в старом стиле.

13 голосов
/ 23 сентября 2008

Они логически идентичны, но в более ранних версиях Oracle, которые использовали синтаксис ANSI, часто возникали ошибки с ним в более сложных случаях, поэтому вы иногда сталкиваетесь с сопротивлением разработчиков Oracle при его использовании.

13 голосов
/ 27 августа 2009

[Для получения бонусного балла ...]

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

Как и все остальные, они функционально одинаковы, однако СОЕДИНЕНИЕ более четко выражает намерение. Следовательно, может помочь оптимизатору запросов в некоторых случаях в текущих версиях Oracle (я понятия не имею, так ли это), может помочь оптимизатору запросов в будущих версиях Oracle (нет - у кого-то есть идея), или может помочь, если вы смените поставщика базы данных.

7 голосов
/ 04 декабря 2008

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

Также можно избежать непреднамеренных декартовых продуктов, используя версию join.

Третий эффект - более легкий для чтения SQL с более простым условием WHERE.

6 голосов
/ 04 июня 2009

Не забывайте, что в Oracle, если атрибуты ключа соединения имеют одинаковые имена в обеих таблицах, вы также можете записать это как:

select *
from Table1 inner join Table2 using (ID);

Конечно, у него тоже есть тот же план запросов.

3 голосов
/ 01 июля 2016

В сценарии, где таблицы находятся в 3-й нормальной форме, соединения между таблицами не должны изменяться. То есть присоединяйтесь к ЗАКАЗЧИКАМ, и ПЛАТЕЖИ всегда должны оставаться неизменными.

Однако мы должны отличать объединения от фильтров . Объединения связаны с отношениями, а фильтры - с разделением целого.

Синтаксис SQL-92 побуждает нас разделить обе концепции, и он предпочтительнее старого синтаксиса, который ставит оба, объединения и фильтры в предложение WHERE, которое является более громоздким.

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