使用CROSS APPLY的主要目的是什么?
我已经阅读(模糊地,通过 Internet 上的帖子),cross apply如果您正在分区,则在选择大型数据集时可能会更有效。(想到分页)
cross apply
我也知道CROSS APPLY不需要 UDF 作为右表。
CROSS APPLY
在大多数INNER JOIN查询(一对多关系)中,我可以将它们重写为 use CROSS APPLY,但它们总是给我等效的执行计划。
INNER JOIN
谁能给我一个很好的例子,说明什么时候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
谁能给我一个很好的例子,说明何时 CROSS APPLY 在 INNER JOIN 也可以工作的情况下有所作为?
详细性能对比见我博客中的文章:
CROSS APPLY在没有简单JOIN条件的事情上效果更好。
JOIN
此选项从以下每条记录中选择3最后一条记录:t2``t1
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‘s 和 window 函数执行类似的操作:
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 KEYon的 about 记录表id。
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几秒钟,而这个:
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
是瞬间的。