Какая разница в производительности при использовании оператора = vs IN с критериями EXISTS? - PullRequest
0 голосов
/ 19 июня 2019

В SQL-сервере при использовании критериев WHERE EXISTS существует ли разница в производительности при использовании оператора = vs IN?

Пример:

SELECT
    customer_id,
    first_name,
    last_name
FROM
    sales.customers c
WHERE
    EXISTS (
        SELECT *
        FROM sales.orders o
        WHERE customer_id = c.customer_id --we can also replace = with IN - for example customer_id IN c.customer_id or say c.customer_id IN customer_id
    )

Другой пример:

SELECT
    customer_id,
    first_name,
    last_name
FROM
    sales.customers c
WHERE
    EXISTS (
        SELECT *
        FROM #Customers x --say #Customers is temp table containing a couple of customers for which we want to show the output
        WHERE c.customer_id = x.customer_id --we can also replace = with IN - for example c.customer_id IN x.customer_id or say x.customer_id IN c.customer_id
    )

Этот вопрос помечен как дубликат этого . Этот вопрос ре. СУЩЕСТВУЕТ ПРОТИВ IN. В то время как мой вопрос re = vs IN при использовании EXISTS

Ответы [ 2 ]

2 голосов
/ 19 июня 2019

Без разницы вообще.

Когда вы пишете

WHERE A IN(B)

Это то же самое, что и запись

WHERE A = B

Если A или B - это столбец, выражение иликонстанта не меняет природу оператора IN.

Если вы пишете

WHERE A IN(B, C)

Это было бы так же, как запись

WHERE A = B OR A = C

Тот факт, что это условие является частью подзапроса внутри оператора EXISTS, не имеет значения.

1 голос
/ 19 июня 2019

Я думаю, вы неправильно понимаете, как коррелированный подзапрос работает вместе с EXISTS.

Равное сравнение (=) оценивает конкретное значение против другого конкретного значения и возвращает true или false. Он не может оценить несколько значений, если вы не добавите дополнительные логические операторы AND / OR. Оператор IN - это просто способ упростить набор OR с помощью операторов =, поэтому его легче читать, как объяснил Зохар в другом ответе.

С другой стороны, оператор EXISTS использует левое полусоединение для проверки существования конкретной записи. EXISTS используется в логических контекстах всякий раз, когда вы хотите проверить, существует ли конкретная строка или нет. Механизм SQL прекращает поиск совпадающих строк , как только находит первую . Это цель левого полусоединения и одно из отличий с левым внешним объединением (кроме получения данных таблицы присоединения) и соответствующие суммы строк).

Итак, когда вы пишете:

FROM
    sales.customers c
WHERE
    EXISTS (
        SELECT *
        FROM sales.orders o
        WHERE o.customer_id = c.customer_id
    )

Вы используете коррелированную ссылку на подзапрос customers с orders. Подзапрос используется в контексте оператора EXISTS, он будет выполнять поиск движка для каждой строки sales.customers, если в sales.orders есть строка не менее 1, удовлетворяющая этому условию :

WHERE o.customer_id = c.customer_id

Это условие будет отображаться как false для каждого заказа, который не от клиента, которого мы в настоящее время проверяем. Двигатель будет игнорировать эти строки, потому что мы ищем существование. Будут возвращены только строки из customers, имеющие customer_id, который создает строку в подзапросе.

Если мы изменим условие на IN:

FROM
    sales.customers c
WHERE
    EXISTS (
        SELECT *
        FROM sales.orders o
        WHERE o.customer_id IN (c.customer_id)
    )

Подзапрос проверит наличие в таблице sales.orders, удовлетворяющее условию:

WHERE o.customer_id IN (c.customer_id)

Это тот же c.customer_id, на который мы ссылались в примере =. Поведение для двигателя будет таким же, как в предыдущем примере; проверьте, есть ли хотя бы одна строка в orders, соответствующая customer_id из customers.

Следовательно, и =, и IN будут работать одинаково.

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