SQL JOIN против производительности? - PullRequest
150 голосов
/ 29 июля 2009

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

Ответы [ 7 ]

180 голосов
/ 29 июля 2009

Вообще говоря, 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.

Подробнее об эффективности смотрите в этой статье в моем блоге:

26 голосов
/ 29 июля 2009

Забавно, что вы упомянули, что я сделал пост в блоге на эту тему.

См. Oracle против MySQL против SQL Server: агрегация против объединений

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

4 голосов
/ 29 июля 2009

Интересное описание логических различий: SQL Server: JOIN против IN против EXISTS - логическое различие

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

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

4 голосов
/ 29 июля 2009

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

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

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

Марк

3 голосов
/ 19 февраля 2013

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

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

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

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

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

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

3 голосов
/ 29 июля 2009

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

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

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

1 голос
/ 29 июля 2009

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

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