Производительность SQL JOIN vs IN?

У меня есть случай, когда использование JOIN или IN даст мне правильные результаты... Что обычно имеет лучшую производительность и почему? Насколько это зависит от того, какой сервер баз данных вы используете? (FYI Я использую MSSQL)

Ответ 1

Вообще говоря, IN и JOIN - разные запросы, которые могут давать разные результаты.

SELECT  a.*
FROM    a
JOIN    b
ON      a.col = b.col

не совпадает с

SELECT  a.*
FROM    a
WHERE   col IN
        (
        SELECT  col
        FROM    b
        )

если b.col не является уникальным.

Однако это синоним первого запроса:

SELECT  a.*
FROM    a
JOIN    (
        SELECT  DISTINCT col
        FROM    b
        )
ON      b.col = a.col

Если столбец соединения UNIQUE и помечен как таковой, оба этих запроса дают тот же план в SQL Server.

Если это не так, то IN быстрее, чем JOIN на DISTINCT.

См. эту статью в своем блоге для подробностей о производительности:

Ответ 3

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

Как правило, я думаю, что если у вас есть индексы в столбцах внешнего ключа, и если вы используете только (или в основном) условия INNER JOIN, тогда JOIN будет немного быстрее.

Но как только вы начнете использовать OUTER JOIN, или если вам не хватает индексов внешнего ключа, IN может быть быстрее.

Марк

Ответ 4

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

Я не уверен, какую версию MSSQL вы используете, но вы можете получить графическую версию SQL Server 2000 в анализаторе запросов. Я уверен, что эта функциональность скрывается в некоторых случаях в SQL Server Studio Manager в более поздних версиях.

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

Ответ 5

Интересная запись о логических различиях: SQL Server: JOIN vs IN vs EXISTS - логическая разница

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

Вам нужно подключить его к Query Analyzer и попробовать и увидеть разницу. Также просмотрите План выполнения запросов и попытайтесь минимизировать шаги.

Ответ 6

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

Итак, если вас интересуют только значения из таблицы a, вы можете использовать этот запрос:

SELECT  a.*
FROM    a
WHERE   EXISTS (
    SELECT  *
    FROM    b
    WHERE   b.col = a.col
    )

Разница может быть огромной, если col не индексируется, потому что db не обязательно должен найти все записи в b, которые имеют одинаковое значение в col, он должен только найти самый первый. Если в b.col нет индекса и большого количества записей в b, сканирование таблицы может быть последствием. С IN или JOIN это будет полное сканирование таблицы, с EXISTS это будет только частичное сканирование таблицы (пока не будет найдена первая совпадающая запись).

Если есть множество записей в b, которые имеют одинаковое значение col, вы также будете тратить много памяти на чтение всех этих записей во временное пространство, только чтобы убедиться, что ваше условие выполнено. С помощью существует это обычно можно избежать.

Я часто обнаружил EXISTS быстрее, чем IN, даже если есть индекс. Это зависит от системы баз данных (оптимизатора), данных и, наконец, не в последнюю очередь от типа используемого индекса.

Ответ 7

Оптимизатор должен быть достаточно умным, чтобы дать вам одинаковый результат в любом случае для обычных запросов. Проверьте план выполнения, и они должны дать вам то же самое. Если они этого не сделают, я, как правило, считаю, что JOIN будет быстрее. Тем не менее, все системы отличаются друг от друга, поэтому вы должны точно определить код в своей системе.