Внутреннее соединение против Где

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

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

и

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

?

Ответ 1

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

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

Ответ 2

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

Ответ 3

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

Ответ 4

Использование JOIN упрощает чтение кода, поскольку оно самоочевидно.

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

Ответ 5

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

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

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

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

Ответ 6

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

Ответ 7

[Для бонусной точки...]

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

Как говорят все остальные, они функционально одинаковы, однако JOIN более четко заявляет о намерениях. Поэтому он может помочь оптимизатору запросов в текущих версиях oracle в некоторых случаях (я не знаю, если это так), это может помочь оптимизатору запросов в будущих версиях Oracle (никто не имеет идеи), или он может помочь, если вы меняете поставщика базы данных.

Ответ 8

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

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

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

Ответ 9

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

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

У этого также есть тот же план запроса, конечно.

Ответ 10

В PostgreSQL нет никакой разницы - они оба приравниваются к одному и тому же тарифному плану. Я на 99% уверен, что и дело для Oracle.

Ответ 11

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

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

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

Ответ 12

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

Ответ 13

Они являются внутренними объединениями, которые делают одно и то же, просто используют новый синтаксис ANSI.

Ответ 14

Верно, что функционально оба запроса должны обрабатываться одинаково. Однако опыт показывает, что если вы выбираете из представлений, которые используют новый синтаксис соединения, важно также структурировать ваши запросы, используя его. Оптимизатор Oracle может запутаться, если представление использует оператор "join", но запрос, обращающийся к представлению, использует традиционный метод соединения в предложении "where".

Ответ 15

Хотя идентичность двух запросов кажется очевидной, иногда случаются некоторые странные вещи. Я пришел с запросом, у которого есть разные планы выполнения при перемещении предиката соединения из JOIN в WHERE в Oracle 10g (для плана WHERE лучше), но я не могу воспроизвести эту проблему в упрощенных таблицах и данных. Я думаю, это зависит от моих данных и статистики. Оптимизатор - довольно сложный модуль, и иногда он ведет себя магически.

Вот почему мы не можем ответить на этот вопрос вообще, потому что это зависит от внутренних компонентов БД. Но мы должны знать, что ответ должен быть "без различий".

Ответ 16

У меня была эта головоломка сегодня, когда мы проверяли одно из наших сроков выпуска в производство, изменили внутреннее соединение на столе, построенном из XML-корма, на предложение "where" вместо этого.... среднее время выполнения теперь составляет 80 мс за 1000 казни, тогда как до среднего exec было 2,2 секунды... существенная разница в плане выполнения - это исчезновение ключевого поиска... Сообщение, которое вы не знаете, пока не проведете тестирование с использованием обоих методов.

приветствий.

Ответ 18

Как сказал kiewik, план выполнения тот же.

Инструкция JOIN читается легче, что упрощает не забывать условие ON и получение декартова продукта. Эти ошибки могут быть довольно сложными для обнаружения в длинных запросах с использованием нескольких объединений типа: SELECT * FROM t1, t2 WHERE t1.id = t2.some_field.

Если вы забудете только одно условие соединения, вы получите очень длинный запрос, возвращающий слишком много записей... действительно слишком много. Некоторые poeple используют DISTINCT для исправления запроса, но он все еще очень долго выполняется.

Точно, почему использование JOIN-инструкции, безусловно, является лучшей практикой: лучшей ремонтопригодностью и лучшей читабельностью.

Кроме того, если я хорошо помню, JOIN оптимизирован относительно использования памяти.