最近,我有一个性能调优的经验,我想在这里分享它,并试图理解为什么会发生这种改进。
在我的一个过程中,我想基于其他记录的存在返回一个数据集。
我的查询:
IF (SELECT COUNT(1) FROM ...) > 0
SELECT …
该查询耗时约5秒钟。
我进行了更改,并将
IF
语句的输出分配给了一个变量,然后对其进行了检查。DECLARE @cnt INT = 0
SELECT @cnt = COUNT(1) FROM …
IF @cnt > 0
SELECT …
该程序只需不到1秒的时间即可运行。
我也尝试了
IF EXISTS
,但是在改进之前(5秒)得到了相同的结果。我非常想知道为什么编译器的行为会有如此大的不同,以及对此是否有任何特殊的答案。
谢谢
最佳答案
这里有两个部分。
1)SQL Server优化器转换
IF (SELECT COUNT(1) FROM ...) > 0
SELECT …
进入
IF EXISTS(SELECT 1 FROM ...)
SELECT …
我已经看到亚当·马汉尼(Adam Machanic)在他对安德鲁·凯利(Andrew Kelly)Exists Vs. Count(*) - The battle never ends对帖子的评论中指出了这一点:
亚当在那里提供了一个演示。
2)有时候
EXISTS
比COUNT
差:IF EXISTS taking longer than embedded select statement
Check existence with EXISTS outperform COUNT! … Not?
像Paul White wrote一样:
如果您的数据分布不正确,或者您希望在大多数情况下
COUNT
为零(即无论如何都要扫描整个表以获取答案),那么您应该尝试获得没有行目标的计划(即没有EXISTS
)。您已经发现的一种显而易见的方法是将
COUNT
的结果保存到变量中。关于sql - 为什么将查询的计数分配给变量比直接检查要好呢?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/34912804/