CROSS APPLY vs OUTER APPLY速度差

我正在使用CROSS APPLY来join用户和GeoPhone表,一切工作都很快,但现在我有Phone列的NULL值的用户。 交叉应用在最终输出中跳过这些行。 所以我切换到OUTER APPLY。 但是它的工作速度要慢得多(当总输出行数增加1000倍时,速度要慢15倍以上)。

SELECT TOP (10000) dbo.Users.Login, dbo.Users.Phone, GeoPhone.Country FROM dbo.Users CROSS APPLY (SELECT TOP 1 Country FROM dbo.GeoPhone WHERE dbo.Users.Phone <= dbo.GeoPhone.[End]) GeoPhone 

与:

 SELECT TOP (10000) dbo.Users.Login, dbo.Users.Phone, GeoPhone.Country FROM dbo.Users OUTER APPLY (SELECT TOP 1 Country FROM dbo.GeoPhone WHERE dbo.Users.Phone <= dbo.GeoPhone.[End]) GeoPhone 

我试图理解为什么。 正如我所看到的执行计划是不同的。 但理论上我看不到任何可能导致这种放缓的计算。

有任何想法吗?

我最终的解决scheme:

 SELECT TOP (10000) dbo.Users.Login, dbo.Users.Phone, GeoPhone.Country FROM dbo.Users CROSS APPLY (SELECT TOP 1 Country FROM dbo.GeoPhone WHERE ISNULL(dbo.Users.Phone, 0) <= dbo.GeoPhone.[End]) GeoPhone 

这为空电话(这是“UNKNOWN”已经为我的情况)的第一范围分配非空电话和国家的实际国家。 出于某种原因WHERE dbo.Users.Phone <= dbo.GeoPhone.[End] OR dbo.Users.Phone IS NULL的结果相同,但速度较慢。

请随时对此发表评论。

交叉应用是MSSQL特定的… 微软在APPLY

APPLY将导致右侧查询在左侧查询中的每个结果中执行一次。 CROSS只考虑像INNER JOIN这样的匹配行。 使用OUTER考虑左侧查询中的所有行。 额外的行受到伤害。

我build议你重新configuration你的右侧查询来显式接受NULL而不是使用OUTER APPLY。

你可以试试这个:

 SELECT TOP (10000) dbo.Users.Login, dbo.Users.Phone, GeoPhone.Country FROM dbo.Users CROSS APPLY (SELECT TOP 1 Country FROM dbo.GeoPhone WHERE dbo.Users.Phone <= dbo.GeoPhone.[End]) GeoPhone UNION ALL SELECT TOP (10000) dbo.Users.Login, dbo.Users.Phone, NULL AS Country FROM dbo.Users WHERE dbo.Users.Phone IS NULL 

确保在dbo.Users.Phone上有一个索引