производительность, связанная с присоединением и где - PullRequest
3 голосов
/ 21 ноября 2011

Я могу получить тот же результат с предложением where внутри объединения или предложением where вне объединения, например:

select *
from a
join b on b.id = a.id and b.type = 1

или

select *
from a
join b on b.id = a.id
where
    b.type = 1

Что лучше? Почему?

ps: не стесняйтесь редактировать мой заголовок, я не знаю, как правильно назвать вопрос.

Ответы [ 6 ]

3 голосов
/ 21 ноября 2011

Для INNER JOIN это не имеет никакого значения ни с точки зрения производительности, ни с точки зрения возвращаемых результатов. Но для OUTER (LEFT/RIGHT/FULL) JOIN набор результатов будет отличаться, так как предложение WHERE фильтрует строки, возвращаемые JOIN, а в случае OUTER (LEFT/RIGHT/FULL) JOIN могут быть возвращены «обнуляемые» записи, поэтому набор результатов будет шире. (Очевидно, что для больших наборов данных условие в OUTER (LEFT/RIGHT/FULL) JOIN может работать быстрее)

2 голосов
/ 21 ноября 2011

Неважно, когда результат одинаков. База данных создаст один и тот же план выполнения для обоих запросов.

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

select *
from a
left join b on b.id = a.id and b.type = 1

Однако это ограничит количество возвращаемых записей, фактически превратив левое соединение во внутреннее соединение, но, скорее всего, с худшей производительностью:

select *
from a
left join b on b.id = a.id
where b.type = 1
2 голосов
/ 21 ноября 2011

Регулятор запросов SQL Server скомпилирует его с точно таким же планом запроса.

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

1 голос
/ 21 ноября 2011

План выполнения запросов (в SQL Management Studio) можно использовать для проверки того, что этот и многие другие запросы выполняются одинаково.

Планы выполнения - лучший инструмент для написания лучших запросов.

1 голос
/ 21 ноября 2011

Мы не можем сказать, какой из них лучше вообще.Производительность зависит от ваших данных, ваших индексов и способа, которым оптимизатор запросов обрабатывает запрос.Чтобы действительно сказать, что лучше, вы должны запустить Explain Plan на обоих.Это даст вам конкретную информацию о том, что лучше для данного конкретного случая.

0 голосов
/ 21 ноября 2011

Использование папа Sybase ASE 15.0 и без статистики в обеих таблицах:

Первый запрос

STEP 1
    The type of query is SELECT.

    FROM TABLE
        b
    Nested iteration.
    Table Scan.
    Forward scan.
    Positioning at start of table.
    Using I/O Size 2 Kbytes for data pages.
    With LRU Buffer Replacement Strategy for data pages.

    FROM TABLE
        a
    Nested iteration.
    Table Scan.
    Forward scan.
    Positioning at start of table.
    Using I/O Size 2 Kbytes for data pages.
    With LRU Buffer Replacement Strategy for data pages.

Второй запрос

STEP 1
    The type of query is SELECT.

    FROM TABLE
        b
    Nested iteration.
    Table Scan.
    Forward scan.
    Positioning at start of table.
    Using I/O Size 2 Kbytes for data pages.
    With LRU Buffer Replacement Strategy for data pages.

    FROM TABLE
        a
    Nested iteration.
    Table Scan.
    Forward scan.
    Positioning at start of table.
    Using I/O Size 2 Kbytes for data pages.
    With LRU Buffer Replacement Strategy for data pages.

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

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