为什么在if语句中包装TSQL查询会显着增加其运行时间?

Tri*_*nko 14 sql t-sql performance if-statement

当以两种不同的方式运行相同的查询时,我有奇怪的性能差异.从字面上看,唯一的区别是它是否包含在if语句中.

这个查询实际上是一个较大的查询的一部分,但我已将其视为罪魁祸首.

单独运行查询几乎立即返回(返回0)

select COUNT(*) from Responses r where r.ResponseID not in (
    select ResponseID from data.GamingReport_Computerized
))
Run Code Online (Sandbox Code Playgroud)

最终,我想避免根据该查询的结果运行复杂的计算,所以我将它包装在if语句中,但运行时间要长得多(~10秒),我无法弄清楚原因:

if (0 = (select COUNT(*) from Responses r where r.ResponseID not in (
    select ResponseID from data.GamingReport_Computerized
)))
begin select 'update will be skipped to save time' end
else begin select 'missing rows will be inserted' end
Run Code Online (Sandbox Code Playgroud)

数据集不会改变,所以在这两种情况下结果都是零/'更新将被跳过',然而运行同一查询的这两个版本总是导致第一个版本快速完成,第二个版本大约需要10-12秒完成.

更新:这是用于比较的查询执行计划的屏幕截图.他们为什么如此不同?这对我来说非常意外.

查询执行计划 详细索引扫描/寻求性能

更新2:为了回应评论中的建议,我想提一下,以下查询与上面的第二个版本完全相同,具有相同的执行计划且性能没有提高(即使用'exists'而不是比较count(*)零到没有区别).

if exists(select 1 from Responses r where r.ResponseID not in (
    select ResponseID from data.GamingReport_Computerized
))
begin select 'missing rows will be inserted' end
else begin select 'update will be skipped to save time' end
Run Code Online (Sandbox Code Playgroud)

小智 1

我以前遇到过这个问题(好几次)。您能否检查索引是否碎片化(必要时对其进行碎片整理)以及统计信息是否最新?这可能会对性能产生相当大的影响,并且很可能是问题所在(因为查找比扫描花费的时间更长)。