为什么选择SELECT到临时表而不是MERGE并不比仅从源查询中合并要慢呢?

时间:2018-11-07 11:44:26

标签: sql sql-server tsql query-optimization

这里是使用表值函数的结果的合并:

MERGE
    Table1 d
USING
    dbo.tvf_Table1(@StartDate, @EndDate) s ON d.ID = s.ID
WHEN MATCHED THEN UPDATE
    SET Dest1 = Src1, Dest2 = Src2, Dest3 = Src3
WHEN NOT MATCHED THEN INSERT
    VALUES(ID, Src1, Src2, Src3);

在我的环境中,该过程大约花费了30秒(三次运行的平均值)。

这里是相同的MERGE,但这一次将函数结果放在临时表中:

SELECT
    *
INTO
    #Temp1
FROM
    dbo.tvf_Table1(@StartDate, @EndDate)

MERGE
    Table1 d
USING
    #Temp1 s ON d.ID = s.ID
WHEN MATCHED THEN UPDATE
    SET Dest1 = Src1, Dest2 = Src2, Dest3 = Src3
WHEN NOT MATCHED THEN INSERT
    VALUES(ID, Src1, Src2, Src3);

DROP TABLE #Temp1

大约花费了31秒(平均三遍)。

事实上,使用临时表运行54个以上的MERGE大约要比不使用临时表快四分钟。

接受到这几乎是不科学的,我希望添加临时表步骤会大大降低查询速度。毕竟,数据是从A移到B,然后是从B移到C,而不是直接从A移到C。

可能导致这种情况的幕后原因是什么?

2 个答案:

答案 0 :(得分:2)

与表值函数相比,临时表为优化器提供了更多优化信息。

我很高兴您希望写入表的开销会减慢整体速度。但是,合并查询的其余部分也需要进行优化,知道表的确切大小有助于优化器改善总体计划。

答案 1 :(得分:0)

提供给临时表的数据量不是太大,服务器应该能够将所有数据保留在内存中,而不必将其溢出到磁盘上。因此,与B相比,A-> BB-> C中的C非常便宜A)。通常,您希望I / O成本会在直接查询中淹没其他大多数成本。

在宏伟的计划中,如果单个MERGE的性能足够好,我还是会比较喜欢它。不要试图通过将任务分解为一系列子任务来帮助SQL Server-这是优化程序的工作,尽管它可能并不总是选择最佳计划,但通常会选择一个足够好的计划。