Когда я должен использовать крест применить поверх внутреннего соединения? - PullRequest
855 голосов
/ 16 июля 2009

Какова основная цель использования CROSS APPLY ?

Я прочитал (смутно, через сообщения в Интернете), что cross apply может быть более эффективным при выборе больших наборов данных, если вы создаете разделы. (Пейджинг приходит на ум)

Я также знаю, что CROSS APPLY не требует UDF в качестве правой таблицы.

В большинстве INNER JOIN запросов (отношения один-ко-многим) я мог бы переписать их для использования CROSS APPLY, но они всегда дают мне эквивалентные планы выполнения.

Может ли кто-нибудь привести хороший пример того, когда CROSS APPLY имеет значение в тех случаях, когда INNER JOIN также будет работать?


Edit:

Вот тривиальный пример, когда планы выполнения точно такие же. (Покажите мне, где они отличаются и где 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

Ответы [ 13 ]

3 голосов
/ 08 марта 2012

Что ж, я не уверен, что это является причиной использования Cross Apply против Inner Join, но на этот вопрос я получил ответ в сообщении на форуме с использованием Cross Apply, поэтому я не уверен, существует ли такой же метод с использованием Inner Регистрация:

Create PROCEDURE [dbo].[Message_FindHighestMatches]

-- Declare the Topical Neighborhood
@TopicalNeighborhood nchar(255)

AS НАЧАТЬ

-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON

Create table  #temp
(
    MessageID         int,
    Subjects          nchar(255),
    SubjectsCount    int
)

Insert into #temp Select MessageID, Subjects, SubjectsCount From Message

Select Top 20 MessageID, Subjects, SubjectsCount,
    (t.cnt * 100)/t3.inputvalues as MatchPercentage

From #temp 

cross apply (select count(*) as cnt from dbo.Split(Subjects,',') as t1
             join dbo.Split(@TopicalNeighborhood,',') as t2
             on t1.value = t2.value) as t
cross apply (select count(*) as inputValues from dbo.Split(@TopicalNeighborhood,',')) as t3

Order By MatchPercentage desc

drop table #temp

END

2 голосов
/ 29 апреля 2018

Суть оператора APPLY заключается в том, чтобы разрешить корреляцию между левой и правой сторонами оператора в предложении FROM.

В отличие от JOIN, корреляция между входами не допускается.

Говоря о корреляции в операторе APPLY, я имею в виду, что справа мы можем поместить:

  • производную таблицу - как коррелированный подзапрос с псевдонимом
  • табличную функцию -концептуальное представление с параметрами, где параметр может ссылаться на левую сторону

Оба могут возвращать несколько столбцов и строк.

1 голос
/ 06 октября 2015

Возможно, это старый вопрос, но мне все еще нравится возможность CROSS APPLY упростить повторное использование логики и обеспечить механизм «цепочки» для результатов.

Я предоставил SQL Fiddle ниже, который показывает простой пример того, как вы можете использовать CROSS APPLY для выполнения сложных логических операций над вашим набором данных без каких-либо проблем. Отсюда нетрудно экстраполировать более сложные вычисления.

http://sqlfiddle.com/#!3/23862/2

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