CROSS APPLY vs OUTER APPLY速度差异

Den*_*nis 51 sql t-sql sql-server performance

我使用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
Run Code Online (Sandbox Code Playgroud)

与:

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
Run Code Online (Sandbox Code Playgroud)

我想知道为什么.我认为执行计划是不同的.但理论上我看不到任何可能导致这种放缓的计算.

有任何想法吗?

我的最终解决方案:

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
Run Code Online (Sandbox Code Playgroud)

这为非电话分配了实际的国家/地区,并为第一个范围分配了空电话(对于我的情况已经是"未知").出于某种原因WHERE dbo.Users.Phone <= dbo.GeoPhone.[End] OR dbo.Users.Phone IS NULL,结果相同,但速度要慢得多.

请随时评论这个.

Mag*_*eer 73

CROSS APPLY是MSSQL特有的...... Microsoft在APPLY上

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

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

  • 谢谢Magicianeer,在您的消息之后我试图重新制定右侧查询并找到快速解决方案.我把它添加到第一条消息. (2认同)

A-K*_*A-K 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
Run Code Online (Sandbox Code Playgroud)

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