我只是想知道是否存在插入/删除组合比更新其他插入函数更快的常见情况。
这是我的具体例子。
我必须使用一次包含 1000 条记录的页面更新数据库。(我无法合并页面)。
这些记录中约有 5% 或 50 行是重复记录,需要“更新”而不是作为全新记录插入。
我认为不是“基于 ID 的更新,否则插入新行”的典型功能,而是在最后一次“插入所有内容”并删除重复项可能会更快。
两个原因:
并行性。如果我希望多个进程同时处理此任务,那么......如果我有很大的提交大小和同时搜索和更新 ID 的事务,我可能会遇到行锁。通过“插入所有内容”并稍后删除“旧”记录,我可以同时拥有无限个进程写入数据。
我觉得在最后优化一个大的“删除查找”很容易。它看起来像下面这样:
with CTE as ( select primary_id,update_date, rn = row_number()over(partition by primary_id order by update_date desc) from MyTable ) delete from CTE where rn > 1
我的意思是性能提升 - 我只是想知道这是否违反最佳实践。有人能看出为什么插入 + 删除重复项似乎比“更新,如果找不到,插入”更快吗?
我可以看到一个危险是数据加载运行时有一段时间表不准确(在删除之前)。但是在任何更新过程中这不是真的吗?
这也将是数据仓库的暂存表,而不是实时使用中的数据。我只是想知道为什么我没有更频繁地看到这种方法。
插入和删除实际上比实现相同最终结果的单个更新更快的原因有很多。我什至不打算列出所有注意事项,但例如:
影响索引键的更新可能看起来是从执行计划进行就地更新,但在最低级别上并非如此。影响索引键的更新会导致在 SQL Server 2005 及更高版本中的存储引擎级别进行单独的删除和插入操作。
更改唯一索引中键值的更新通常意味着 SQL Server 必须在执行计划中引入Split/Sort/Collapse 组合,以避免短暂的唯一键冲突。Split 显式地将每个更新转换为单独的删除和插入操作。额外运算符(尤其是排序)的成本通常会导致性能下降。插入或删除到唯一索引的计划不需要这种相同的保护,但由于其他原因可能仍会看到 Split 运算符。
对于根本不适用于更新(或删除)的插入,存在可用的内部优化。其中一些与最少的日志记录相关联,而另一些则需要提示或跟踪标志(如610)。其他优化不需要跟踪标志或提示,并且不会在执行计划中公开。
这是关键点。我可以告诉您,我的经验是更新和删除在 SQL Server 中的优化程度通常不如插入,但关键是要在您的环境中进行测试。插入和删除并不总是比单个更新快,就像单独的操作并不总是比单个操作快一样
MERGE
(尽管这可能更常见)。甚至在某些情况下,插入后跟更新(!) 可能比单次更新更快。虽然与您的示例没有直接关系,但您可能会在我的文章“优化更新查询”中找到相关的详细信息。
还相关: