首页 > 解决方案 > 为什么 SELECT 到临时表然后 MERGE 并不比从源查询中 MERGE 慢?

问题描述

这是使用表值函数结果的 MERGE:

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 秒(平均超过 3 次运行)。

这是相同的 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,使用临时表比没有使用临时表快大约 4 分钟。

接受这几乎不科学,我预计添加临时表步骤会显着减慢查询速度。毕竟,数据是从 A 移动到 B,然后从 B 移动到 C,而不是直接从 A 移动到 C。

可能导致这种情况的幕后发生了什么?

标签: sqlsql-servertsqlquery-optimization

解决方案


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

我可以理解您期望写入表的开销会减慢整体速度。但是,合并查询的其余部分也需要优化,知道表的确切大小有助于优化器改进整体计划。


推荐阅读