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上有一个索引