使用の主な目的は何ですか?クロスアプライ?
パーティション分割している場合、大規模なデータセットを選択するときに効率が上がる可能性があると(漠然と、インターネット上の投稿を通じて)読んだことがあります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
の最後のレコードを選択します:t2
t1
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
しかし、これでは読みにくく、効率も悪くなる可能性があります。
アップデート:
確認しました。
master
は20,000,000
、 に関する約 件のレコードのテーブルです。PRIMARY KEY
id
このクエリ:
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
即時です。