sql - IF NOT EXISTS vs @@ROWCOUNT - 性能

标签 sql sql-server sql-server-2005

我应该使用哪一种以获得最佳性能?

这个:

IF NOT EXISTS (...where Id = 'x')
    INSERT...'x'
ELSE 
    UPDATE...WHERE Id = 'x'

或者这个:
UPDATE...WHERE Id = 'x'
if @@ROWCOUNT = 0
    INSERT...'x'

最佳答案

我认为您提出的两个版本之间的性能无关紧要。

对我来说,真正的问题是如何处理语句之间的数据库事件。如果有人尝试在第一个示例中的 NOT EXISTS 检查或第二个示例中的 UPDATE 之后立即插入一行,会发生什么情况?这是在交易中发生的吗?如果是这样,您的隔离级别是多少?
MERGE会更好,但你说这不是一个选项,因为你需要支持 SQL Server 2005。

我们为 SQL Server 2005 所做的是同时执行 INSERTUPDATE .从 UPDATE 开始,所以你不要UPDATE您刚刚使用 INSERT 创建的行:

UPDATE Persons
SET PersonName = 'Ted'
WHERE PersonID = 6

;WITH Data(Id, Name)
AS (SELECT 6, 'Ted')
INSERT MyTable (PersonId, PersonName)
SELECT Id, Name
FROM Data
    LEFT JOIN Persons ON PersonId = Id
WHERE PersonId IS NULL -- the person does not already exist

此例程对于较大的批量操作更有意义,其中一些数据可能已经存在,但它可以用于单个更新。

另一个考虑因素:您是否需要跟踪其他人是否更改了行?如果是这样,我建议添加 timestamp (在较新版本中为 rowversion)列并且失败了 UPDATE如果时间戳不同。

例如,假设 Alice 正在编辑名为“Bill”的个人 ID 6。在打开 Bill 的行后,Charlie 打开 Bill 的行,输入一些信息并保存更改。当 Alice 保存她的更改时,她将覆盖 Charlie 的更改。

关于sql - IF NOT EXISTS vs @@ROWCOUNT - 性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24963750/

相关文章:

sql - 如何使用 INFORMATION_SCHEMA 查找默认约束?

sql - MYSQL为什么min会比max大?

sql-server - 故障转移后如何连接到镜像 SQL Server?

sql-server-2005 - 关于嵌套存储过程

sql-server-2005 - BOL 中的 BREAK 描述

javascript - 如何在 ASP.NET C# 页面加载之前获取动态创建的控件的值

sql - 将 R Dataframe 中的多行插入 Oracle 数据库

sql-server - 为回溯运行 Azure 数据工厂单个事件

sql - 比较 SQL Server 中两个日期范围之间的数据

sql - 使用SELECT执行INSERT以插入多个记录