我应该使用哪一个才能获得最佳性能?
这一个:
IF NOT EXISTS (...where Id = 'x')
INSERT...'x'
ELSE
UPDATE...WHERE Id = 'x'
或者这个:
UPDATE...WHERE Id = 'x'
if @@ROWCOUNT = 0
INSERT...'x'
答案 0 :(得分:6)
我认为你提出的两个版本之间的性能并不重要。
对我而言,真正的问题是如何处理语句之间的数据库活动。如果有人在第一个示例中的NOT EXISTS检查或第二个示例中的UPDATE之后立即尝试插入行,会发生什么?这是在交易中发生的吗?如果是这样,你的隔离级别是什么?
MERGE
会更好,但是你说这不是一个选项,因为你需要支持SQL Server 2005.
我们为SQL Server 2005所做的是同时执行INSERT
和UPDATE
。从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的更改。
答案 1 :(得分:1)
如果您不确定,只需使用SET STATISTICS TIME ON / OFF来实际测量它。例如:
SET STATISTICS TIME ON
-- put your SQL to test here
SET STATISTICS TIME OFF
现在选择块并执行它(你必须实际执行它,所以使用测试环境和数据库的副本)。您将获得有关所发生事件的确切信息,并且应该能够使用它来确定哪个更快。
正如其他人所指出的,结果可能会有所不同,具体取决于实际使用情况,更多更新或更多插页。