когда выбрать CROSS APPLY и когда EXISTS? - PullRequest
6 голосов
/ 12 марта 2012

Я прочитал, CROSS APPLY точно так же, как JOIN .. и я думаю, что JOIN можно выполнить также с помощью EXISTS (коррелированный подзапрос)

Я запутался, в чем разницас использованием CROSS APPLY и EXISTS?

когда мне следует перейти на CROSS APPLY против EXISTS?

Ответы [ 2 ]

8 голосов
/ 12 марта 2012

CROSS APPLY - это не просто JOIN. JOIN находит совпадающие (или не совпадающие) строки между двумя наборами данных. CROSS APPLY - это метод для выполнения запроса к каждой строке того, к чему вы применяете. Это может действовать как механизм фильтрации, что-то вроде того, как работает JOIN, но он применяет что-то к каждой строке, поэтому об этом нужно думать таким образом.

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

Так что, хотя вы можете получить одинаковые результаты с помощью этих трех различных методов, используйте их, как определено, и вы, как правило, будете правы. Если вы буквально СОЕДИНЯЕТЕ два набора данных, используйте JOIN. Если вы хотите запустить процесс, часто фильтр, для каждой строки в наборе данных, используйте CROSS APPLY. Если вам нужен быстрый фильтр для вероятного положительного совпадения, используйте EXISTS.

0 голосов
/ 21 марта 2018

Ответ Гранта верен на деньги. Но с точки зрения личного стиля я использую исключительно OUTER APPLY.Вот общий шаблон, все три из них делают одно и то же, но с помощью внешнего применения при проверке вы можете кратко закомментировать «WHERE ca2.HasAddress = 'Yes'» и добавить ca2.HasAddress в основной выбор, чтобы убедиться, чтоваш фильтр удаляет нужные записи, тогда как другие два метода фильтрации не обеспечивают одинаковую прозрачность на уровне строк.

SELECT c.CustomerID
FROM SalesLT.Customer c
OUTER APPLY (SELECT TOP 1 'Yes' HasAddress
             FROM SalesLT.CustomerAddress ca
             WHERE c.CustomerID = ca.CustomerID)
             ca2
WHERE ca2.HasAddress = 'Yes'

SELECT c.CustomerID 
FROM SalesLT.Customer c
CROSS APPLY (SELECT TOP 1 'Yes' HasAddress
             FROM SalesLT.CustomerAddress ca
             WHERE c.CustomerID = ca.CustomerID)
             ca2

SELECT c.CustomerID 
FROM SalesLT.Customer c
WHERE EXISTS (SELECT 1
             FROM SalesLT.CustomerAddress ca
             WHERE c.CustomerID = ca.CustomerID)
...