INNER JOIN ではなく CROSS APPLY を使用する必要があるのはどのような場合ですか? 質問する

INNER JOIN ではなく CROSS APPLY を使用する必要があるのはどのような場合ですか? 質問する

使用の主な目的は何ですか?クロスアプライ?

パーティション分割している場合、大規模なデータセットを選択するときに効率が上がる可能性があると(漠然と、インターネット上の投稿を通じて)読んだことがありますcross apply。(ページングが思い浮かびます)

また、CROSS APPLY右テーブルとして UDF は必要ないこともわかっています。

INNER JOINほとんどのクエリ (1 対多の関係)では、 を使用するように書き換えることができます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

ベストアンサー1

INNER JOIN も機能する場合に CROSS APPLY が効果を発揮する良い例を誰か教えてもらえませんか?

詳細なパフォーマンス比較については、私のブログの記事をご覧ください。

CROSS APPLY単純な条件がないものに対してより効果的に機能しますJOIN

これは、の各レコードに対して3の最後のレコードを選択します:t2t1

SELECT  t1.*, t2o.*
FROM    t1
CROSS APPLY
        (
        SELECT  TOP 3 *
        FROM    t2
        WHERE   t2.t1_id = t1.id
        ORDER BY
                t2.rank DESC
        ) t2o

条件を付けて簡単に定式化することはできませんINNER JOIN

CTEとウィンドウ関数を使用すると、次のようなことができるでしょう。

WITH    t2o AS
        (
        SELECT  t2.*, ROW_NUMBER() OVER (PARTITION BY t1_id ORDER BY rank) AS rn
        FROM    t2
        )
SELECT  t1.*, t2o.*
FROM    t1
INNER JOIN
        t2o
ON      t2o.t1_id = t1.id
        AND t2o.rn <= 3

しかし、これでは読みにくく、効率も悪くなる可能性があります。

アップデート:

確認しました。

master20,000,000、 に関する約 件のレコードのテーブルです。PRIMARY KEYid

このクエリ:

WITH    q AS
        (
        SELECT  *, ROW_NUMBER() OVER (ORDER BY id) AS rn
        FROM    master
        ),
        t AS 
        (
        SELECT  1 AS id
        UNION ALL
        SELECT  2
        )
SELECT  *
FROM    t
JOIN    q
ON      q.rn <= t.id

ほぼ30数秒間実行されますが、次のもの:

WITH    t AS 
        (
        SELECT  1 AS id
        UNION ALL
        SELECT  2
        )
SELECT  *
FROM    t
CROSS APPLY
        (
        SELECT  TOP (t.id) m.*
        FROM    master m
        ORDER BY
                id
        ) q

即時です。

おすすめ記事