考虑以下查询:
MERGE [Parameter] with (rowlock) AS target
USING (SELECT @AreaId, @ParameterTypeId, @Value)
AS source (AreaId, ParameterTypeId, Value)
ON (target.AreaId = source.AreaId AND
target.ParameterTypeId = source.ParameterTypeId)
WHEN MATCHED THEN
UPDATE SET target.Value = source.Value, @UpdatedId = target.Id
WHEN NOT MATCHED THEN
INSERT ([AreaId], [ParameterTypeId], [Value])
VALUES (source.AreaId, source.ParameterTypeId, source.Value);
Run Code Online (Sandbox Code Playgroud)
统计 I/O 提供以下输出:
表“参数类型”。扫描计数 0,逻辑读取 2,物理读取 0,预读读取 0,lob 逻辑读取 0,lob 物理读取 0,lob 预读读取 0。
表 'Area'。扫描计数 0,逻辑读取 2,物理读取 0,预读读取 0,lob 逻辑读取 0,lob 物理读取 0,lob 预读读取 0。
表“参数”。扫描计数 1,逻辑读取 4,物理读取 0,预读读取 0,lob 逻辑读取 0,lob 物理读取 0,lob 预读读取 0。
表“工作表”。扫描计数 1,逻辑读 0,物理读 0,预读 0,lob 逻辑读 0,lob 物理读 0,lob 预读 0。
工作表出现在消息选项卡中,这让我认为 tempdb 正在被MERGE.
我在执行计划中没有看到任何表明需要 tempdb 的内容
是否MERGE总是使用 tempdb?
BOL 中是否有任何内容可以解释这种行为?
在这种情况下使用INSERT&UPDATE会更快吗?
剩下

对

这是表结构

(扩展我对这个问题的评论。)
如果没有对AreaIdand组合的唯一约束ParameterTypeId,给定的代码就会被破坏,因为它@UpdatedId = target.Id只会记录一行Id。
除非你告诉它,否则 SQL Server 不能隐式地知道数据的可能状态。应该强制执行约束,或者如果多行有效,则需要更改代码以使用不同的机制来输出Id值。
由于扫描运算符可能会遇到多个匹配的行,因此查询必须急切地假脱机所有匹配项以进行万圣节保护。如注释中所示,约束是有效的,因此添加它不仅会将计划从扫描更改为查找,而且还消除了对表假脱机的需要,因为 SQL Server 将知道将有 0 或从搜索运算符返回 1 行。
| 归档时间: |
|
| 查看次数: |
2191 次 |
| 最近记录: |