2008-09-23 3 views
215

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

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

только для записи, я видел, что запросы возвращают разные результаты только путем перехода от условия соединения к где – BlackTigerX 2010-08-25 18:55:14

+8

@BlackTigerX: разные результаты? Были ли какие-либо внешние соединения? Потому что я не вижу, как будут возникать разные результаты между «внутренним соединением ... на» и помещением эквивалентных критериев присоединения в предложение `where`. – 2011-05-07 04:12:51

+0

в старой версии базы данных оракула не существует `join` – MajidTaheri 2012-05-24 15:58:59

ответ

171

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

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 

И план выполнения запроса с помощью ИНЕКЕ.

-- 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 
62

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

+18

Да, производительность должна быть одинаковой. Но синтаксис SELECT * FROM Table1, Table2 WHERE ... - это ЗЛО! – 2008-09-23 15:31:47

+2

Я нахожу гораздо проще понять IN INER JOINS, чем синтаксис SQL-92. Ваш пробег может отличаться. – 2008-09-23 17:39:50

+22

Я нахожу синтаксис WHERE более легким для чтения, чем INNER JION - я думаю, что это похоже на Vegemite. Большинство людей в мире, вероятно, считают это отвратительным, но дети воспитывают его, любят его. – ScottCher 2008-10-27 18:53:01

3

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

53

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

1

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

2

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

13

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

15

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

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

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

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

24

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

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

1

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

7

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

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

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

6

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

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

Это также имеет тот же план запроса, конечно.

12

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

Использование ПРИСОЕДИНЯЙСЯ синтаксис позволяет легко закомментировать присоединиться как его все включено в одной строке. Это может быть полезным, если вы отлаживаете сложный запрос.

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

0

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

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

0

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

ура.

3

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

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

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

0

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

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

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

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

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