Вообще говоря, IN
отличается от JOIN
тем, что JOIN
может возвращать дополнительные строки, в которых строка имеет более одного совпадения в таблице JOIN
.
Из вашей оценкиПлан выполнения, хотя можно видеть, что в этом случае два запроса семантически совпадают
SELECT
A.Col1
,dbo.Foo(A.Col1)
,MAX(A.Col2)
FROM A
WHERE dbo.Foo(A.Col1) IN (SELECT Col1 FROM B)
GROUP BY
A.Col1,
dbo.Foo(A.Col1)
против
SELECT
A.Col1
,dbo.Foo(A.Col1)
,MAX(A.Col2)
FROM A
JOIN B ON dbo.Foo(A.Col1) = B.Col1
GROUP BY
A.Col1,
dbo.Foo(A.Col1)
Даже если дубликаты вводятся JOIN
, тогда они будутудаляется GROUP BY
, так как он ссылается только на столбцы из левой таблицы.Кроме того, эти повторяющиеся строки не изменят результат, так как MAX(A.Col2)
не изменится.Однако это не относится ко всем агрегатам.Если бы вы использовали SUM(A.Col2)
(или AVG
или COUNT
), то наличие дубликатов изменило бы результат.
Похоже, что SQL Server не имеет никакой логики для различия между агрегатами, такими как MAX
, и такими, как SUM
, и поэтому вполне возможно, что он расширяет все дубликаты, а затем агрегирует их позже и простовыполнять гораздо больше работы.
Расчетное количество агрегируемых строк составляет 2893.54
для IN
против 28271800
для JOIN
, но эти оценки не обязательно будут очень надежными, так как предикат объединенияunsargable.