Какой SQL вы пишете? - PullRequest
       48

Какой SQL вы пишете?

2 голосов
/ 05 августа 2009

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

Шаблон A:

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

Шаблон B:

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

Ответы [ 4 ]

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

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

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

4 голосов
/ 05 августа 2009

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

3 голосов
/ 05 августа 2009

Если вы замените 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 голосов
/ 05 августа 2009

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

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