CROSS APPLY vs OUTER APPLY速度差异

时间:2011-07-17 20:53:04

标签: sql sql-server performance tsql

我使用CROSS APPLY加入用户和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

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

有什么想法吗?

我的最终解决方案:

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

这为空手机分配非空手机和国家的实际国家/地区(对于我的情况已经是“未知”)。出于某种原因,WHERE dbo.Users.Phone <= dbo.GeoPhone.[End] OR dbo.Users.Phone IS NULL会产生相同的结果但速度会慢得多。

请随意发表评论。

2 个答案:

答案 0 :(得分:73)

CROSS APPLY是MSSQL特定的...... Microsoft on APPLY

APPLY会导致右侧查询在左侧查询中按结果执行一次。 CROSS只考虑匹配行,如INNER JOIN。使用OUTER会考虑左侧查询中的所有行。额外的行伤害了。

我建议您重新配置右侧查询以显式接受NULL而不是使用OUTER APPLY。

答案 1 :(得分:11)

你可以试试这个:

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

上有索引