Какова основная цель использования CROSS APPLY ?
Я прочитал (смутно, через сообщения в Интернете), что cross apply
может быть более эффективным при выборе больших наборов данных, если вы разделяете. (Пейджинг приходит на ум)
Я также знаю, что CROSS APPLY
не требует UDF в качестве правой таблицы.
В большинстве INNER JOIN
запросов (отношения «один ко многим») я мог бы переписать их для использования CROSS APPLY
, но они всегда дают мне эквивалентные планы выполнения.
Может ли кто-нибудь дать мне хороший пример того, когда изменится CROSS APPLY
ситуация в тех случаях, когда также INNER JOIN
будет работать?
Редактировать:
Вот тривиальный пример, где планы выполнения точно такие же. (Покажите мне, где они отличаются и где cross apply
быстрее / эффективнее)
create table Company (
companyId int identity(1,1)
, companyName varchar(100)
, zipcode varchar(10)
, constraint PK_Company primary key (companyId)
)
GO
create table Person (
personId int identity(1,1)
, personName varchar(100)
, companyId int
, constraint FK_Person_CompanyId foreign key (companyId) references dbo.Company(companyId)
, constraint PK_Person primary key (personId)
)
GO
insert Company
select 'ABC Company', '19808' union
select 'XYZ Company', '08534' union
select '123 Company', '10016'
insert Person
select 'Alan', 1 union
select 'Bobby', 1 union
select 'Chris', 1 union
select 'Xavier', 2 union
select 'Yoshi', 2 union
select 'Zambrano', 2 union
select 'Player 1', 3 union
select 'Player 2', 3 union
select 'Player 3', 3
/* using CROSS APPLY */
select *
from Person p
cross apply (
select *
from Company c
where p.companyid = c.companyId
) Czip
/* the equivalent query using INNER JOIN */
select *
from Person p
inner join Company c on p.companyid = c.companyId
sql
sql-server
performance
tsql
cross-apply
Джефф Фрикадель Ян
источник
источник
CROSS APPLY
имеет очевидное применение, позволяя множеству зависеть от другого (в отличие отJOIN
оператора), но это не обходится без затрат: оно ведет себя как функция, которая работает над каждым членом левого набора, поэтому в терминах SQL Server это всегда выполняйтеLoop Join
, что почти никогда не является лучшим способом объединения наборов. Так что используйте,APPLY
когда вам нужно, но не злоупотребляйте имJOIN
.Ответы:
См. Статью в моем блоге для подробного сравнения производительности:
INNER JOIN
противCROSS APPLY
CROSS APPLY
лучше работает на вещи, которые не имеют простыхJOIN
условий.Этот выбирает
3
последние записиt2
для каждой записи изt1
:Это не может быть легко сформулировано с
INNER JOIN
условием.Вы, вероятно, могли бы сделать что-то подобное, используя
CTE
функцию s и window:, но это менее читабельно и, вероятно, менее эффективно.
Обновить:
Только что проверил.
master
таблица о20,000,000
записи сPRIMARY KEY
оid
.Этот запрос:
работает в течение почти
30
секунд, а этот:мгновенно
источник
TVF
сINNER JOIN
?CROSS APPLY
, он спрашивал, когда выбратьINNER JOIN
, когда это сработает.lateral join
стандартным (ANSI) SQLcross apply
иногда позволяет вам делать то, что вы не можете сделать сinner join
.Пример (синтаксическая ошибка):
Это синтаксическая ошибка , потому что при использовании с
inner join
табличными функциями можно принимать только переменные или константы качестве параметров . (То есть параметр табличной функции не может зависеть от столбца другой таблицы.)Однако:
Это законно
Изменить: Или, альтернативно, более короткий синтаксис: (ErikE)
Редактировать:
Примечание: Informix 12.10 xC2 + имеет Боковые производные таблицы, а Postgresql (9.3+) имеет Боковые подзапросы, которые можно использовать для аналогичного эффекта.
источник
SELECT
необходимости внутриCROSS APPLY
. Пожалуйста, попробуйтеCROSS APPLY dbo.myTableFun(O.name) F
.Предположим, у вас есть две таблицы.
МАСТЕР СТОЛ
ПОДРОБНАЯ ТАБЛИЦА
Есть много ситуаций , в которых мы должны заменить
INNER JOIN
сCROSS APPLY
.1. Соедините две таблицы на основе
TOP n
результатовПодумайте, нужно ли нам выбирать
Id
иName
изMaster
двух последних дат для каждогоId
изDetails table
.Приведенный выше запрос генерирует следующий результат.
Видите, он генерировал результаты за последние две даты с последними двумя датами,
Id
а затем объединял эти записи только во внешнем запросеId
, что неверно. Должно быть возвращено какIds
1, так и 2, но возвращено только 1, потому что 1 имеет последние две даты. Для этого нам нужно использоватьCROSS APPLY
.и формирует следующий результат.
Вот как это работает. Запрос внутри
CROSS APPLY
может ссылаться на внешнюю таблицу, гдеINNER JOIN
это невозможно сделать (он выдает ошибку компиляции). При нахождении двух последних дат соединение выполняется внутри,CROSS APPLY
т.е.WHERE M.ID=D.ID
.2. Когда нам нужны
INNER JOIN
функциональные возможности с использованием функций.CROSS APPLY
может быть использован в качестве замены,INNER JOIN
когда нам нужно получить результат изMaster
таблицы иfunction
.А вот и функция
который породил следующий результат
ДОПОЛНИТЕЛЬНОЕ ПРЕИМУЩЕСТВО ПРИМЕНЕНИЯ КРЕСТА
APPLY
может быть использован в качестве заменыUNPIVOT
. ЛибоCROSS APPLY
илиOUTER APPLY
может быть использован здесь, которые являются взаимозаменяемыми.Предположим, у вас есть таблица ниже (названа
MYTABLE
).Запрос ниже.
который приносит вам результат
источник
Мне кажется, что CROSS APPLY может заполнить определенный пробел при работе с вычисляемыми полями в сложных / вложенных запросах и сделать их более простыми и удобочитаемыми.
Простой пример: у вас есть DoB, и вы хотите представить несколько связанных с возрастом полей, которые также будут полагаться на другие источники данных (такие как занятость), такие как Age, AgeGroup, AgeAtHiring, MinimumRetirementDate и т. Д., Для использования в приложении конечного пользователя. (Сводные таблицы Excel, например).
Варианты ограничены и редко изящны:
Подзапросы JOIN не могут вводить новые значения в набор данных на основе данных в родительском запросе (он должен стоять самостоятельно).
UDFs аккуратны, но медленны, поскольку имеют тенденцию предотвращать параллельные операции. И быть отдельной сущностью может быть хорошей (меньше кода) или плохой (где код) вещью.
Соединительные столы. Иногда они могут работать, но достаточно скоро вы присоединяетесь к подзапросам с тоннами UNION. Большой беспорядок
Создайте еще одно универсальное представление, предполагая, что ваши вычисления не требуют данных, полученных в середине вашего основного запроса.
Посреднические столы. Да ... это обычно работает, и часто это хороший вариант, поскольку они могут быть проиндексированы и быстры, но производительность также может снизиться из-за того, что операторы UPDATE не параллельны и не позволяют каскадировать формулы (повторно использовать результаты) для обновления нескольких полей внутри то же самое утверждение И иногда вы бы предпочли сделать все за один проход.
Вложенные запросы. Да, в любой момент вы можете поставить круглые скобки для всего запроса и использовать его как подзапрос, в котором вы можете манипулировать как исходными данными, так и вычисляемыми полями. Но вы можете сделать это только до того, как это станет уродливым. Очень страшный.
Повторяющийся код Каково наибольшее значение 3 длинных (CASE ... ELSE ... END) операторов? Это будет читабельным!
Я что-то пропустил? Наверное, поэтому не стесняйтесь комментировать. Но эй, CROSS APPLY - это находка в таких ситуациях: вы просто добавляете простой
CROSS APPLY (select tbl.value + 1 as someFormula) as crossTbl
и вуаля! Ваше новое поле теперь готово к использованию практически так, как оно всегда было в ваших исходных данных.Значения, введенные через CROSS APPLY, могут ...
CROSS APPLY (select crossTbl.someFormula + 1 as someMoreFormula) as crossTbl2
Черт, они ничего не могут сделать!
источник
Перекрестное применение хорошо работает и с полем XML. Если вы хотите выбрать значения узла в сочетании с другими полями.
Например, если у вас есть таблица, содержащая некоторые xml
Использование запроса
Вернет результат
источник
На это уже очень хорошо технически ответили, но позвольте мне привести конкретный пример того, как это чрезвычайно полезно:
Допустим, у вас есть две таблицы: клиент и заказ. У клиентов много заказов.
Я хочу создать представление, которое дает мне подробную информацию о клиентах и о самом последнем заказе, который они сделали. С просто JOINS это потребует некоторых самостоятельных объединений и агрегации, что не очень красиво. Но с Cross Apply это супер просто:
источник
Перекрестное применение может использоваться для замены подзапроса, где вам нужен столбец подзапроса.
подзапрос
здесь я не смогу выбрать столбцы таблицы компании, поэтому, используя перекрестное применение
источник
Я думаю, это должно быть читаемость;)
CROSS APPLY будет несколько уникальным для читателей, которые сообщат им, что используется UDF, который будет применен к каждой строке таблицы слева.
Конечно, есть и другие ограничения, когда CROSS APPLY лучше использовать, чем JOIN, который другие друзья опубликовали выше.
источник
Вот статья, которая объясняет все это, с их разницей в производительности и использованием по сравнению с JOINS.
SQL Server CROSS APPLY и OUTTER APPLY через соединения
Как предлагается в этой статье, нет никакой разницы в производительности между ними для обычных операций объединения (INNER AND CROSS).
Разница в использовании возникает, когда вам нужно выполнить запрос, подобный следующему:
То есть, когда вы должны относиться к функции. Это невозможно сделать с помощью INNER JOIN, что может привести к ошибке «Не удалось связать многокомпонентный идентификатор D.DepartmentID». Здесь значение передается функции при чтении каждой строки. Звучит круто для меня. :)
источник
Ну, я не уверен, является ли это причиной для использования Cross Apply по сравнению с Inner Join, но на этот вопрос я получил ответ в сообщении на форуме с использованием Cross Apply, поэтому я не уверен, существует ли такой же метод с использованием Inner Join:
КАК НАЧАТЬ
КОНЕЦ
источник
Суть оператора APPLY состоит в том, чтобы разрешить корреляцию между левой и правой частью оператора в предложении FROM.
В отличие от JOIN, корреляция между входами не допускается.
Говоря о корреляции в операторе APPLY, я имею в виду, что с правой стороны мы можем поместить:
Оба могут возвращать несколько столбцов и строк.
источник
Возможно, это старый вопрос, но мне все еще нравится возможность CROSS APPLY упростить повторное использование логики и обеспечить механизм «цепочки» для результатов.
Ниже я привел SQL Fiddle, который показывает простой пример того, как вы можете использовать CROSS APPLY для выполнения сложных логических операций над вашим набором данных без каких-либо проблем. Отсюда нетрудно экстраполировать более сложные вычисления.
http://sqlfiddle.com/#!3/23862/2
источник
Хотя большинство запросов, использующих CROSS APPLY, могут быть переписаны с использованием INNER JOIN, CROSS APPLY может обеспечить лучший план выполнения и лучшую производительность, поскольку он может ограничить объединяемый набор еще до того, как произойдет соединение.
Украдено отсюда
источник