2009-08-05 4 views
2

При объединении двух таблиц, в чем разница между двумя блоками ниже и чем лучше подходит?Какой SQL вы пишете?

Pattern A:

SELECT ... 
FROM A 
    INNER JOIN B 
     ON A.PK = B.FK 
WHERE 1=1 
    AND A.Name = "Foo" 
    AND B.Title = "Bar" 

Pattern B:

SELECT ... 
FROM A 
    INNER JOIN B 
     ON A.PK = B.FK 
      AND B.Title = "Bar" 
WHERE 1=1 
    AND A.Name = "Foo" 
+2

Я бы подумал, что запрос optimzier не может волновать; но я не гуру ... – balpha

+0

@balpha: это верно только для * INNER *. Для соединений OUTER существует разница. – Sung

ответ

13

Это будет отличаться от человека к человеку, но я думаю, что вариант А лучше.

Что он делает, он отделяет соединения уровня таблицы от фильтров. Это может быть полезно для запросов с несколькими объединениями и несколькими фильтрами, поскольку оно четко разделяет два типа соединения, которое происходит.

+0

Точно. ON был первоначально введен для разделения условий соединения от фильтров. – Powerlord

4

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

0

Возможно, я ошибаюсь, но я вижу, что 1-й подход является более эффективным. Ваши запросы выполняются наизнанку. Поэтому, когда вы сначала запускаете свое соединение, оно будет работать быстрее только потому, что оно должно совпадать (возможно, с индексом) PK & FK Fields, а не что-либо постороннее, как поле Title (что, вероятно, является varchar, что делает матч еще медленнее). Таким образом, к тому моменту, когда вы дойдете до условия фильтрации, где у вас есть предложение, у вас меньше данных для выполнения сопоставления. Однако все предположения. Интересно, что скажут другие. Не помешало бы увидеть план выполнения на этом :)

+1

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

3

Если вы замените INNER JOIN на OUTER JOIN, будет разница.

В противном случае, эти запросы:

SELECT ... 
FROM A 
INNER JOIN 
     B 
ON  A.PK = B.FK 
WHERE A.Name = "Foo" 
     AND B.Title = "Bar" 

SELECT ... 
FROM A 
INNER JOIN 
     B 
ON  A.PK = B.FK 
     AND B.Title = "Bar" 
WHERE A.Name = "Foo" 

SELECT * 
FROM A, B 
WHERE B.Title = "Bar" 
     AND A.Name = "Foo" 
     AND A.PK = B.FK 

идентичны.

Oracle, MySQL, PostgeSQL и SQL Server будут относиться к ним точно так же, и использовать точно такие же план для всех из них.

Я хотел бы использовать этот один:

SELECT ... 
FROM A 
INNER JOIN 
     B 
ON  B.FK = A.PK 
WHERE A.Name = "Foo" 
     AND B.Title = "Bar" 

если есть ключ один столбец на B.FK, и это одна:

SELECT ... 
FROM A 
INNER JOIN 
     B 
ON  B.FK = A.PK 
     AND B.Title = "Bar" 
WHERE A.Name = "Foo" 

если есть составной ключ на (B.FK, B.title).

В этом случае условия соединения более визуальны.

+0

Вы ненормально правы о том, что существует разница, если вы используете внешнее соединение, поскольку первый шаблон wil преобразует внешнее соединение в внутреннее соединение, а второе не будет, поэтому результаты будут очень разными. – HLGEM

Смежные вопросы