【发布时间】:2011-10-07 06:55:57
【问题描述】:
我使用 CROSS APPLY 来加入用户和 GeoPhone 表,一切都运行得很快,但现在我的用户在电话列中有 NULL 值。交叉应用会在最终输出中跳过这些行。所以我切换到外部应用。但它的运行速度要慢得多(当输出中的总行数仅增加 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 的结果相同,但速度要慢得多。
请随时发表评论。
【问题讨论】:
标签: sql sql-server performance tsql