我们有一个状态表。当状态改变时,我们当前删除旧记录并插入新记录。
我们想知道选择检查它是否存在然后插入或更新会更快。
虽然类似于以下问题,但它不一样,因为我们正在更改单个记录,而另一个问题是进行全部表刷新。
答案 0 :(得分:4)
由于您正在谈论SQL Server 2008,您是否考虑过MERGE?这是一个允许您进行更新或插入的声明:
create table T1 (
ID int not null,
Val1 varchar(10) not null
)
go
insert into T1 (ID,Val1)
select 1,'abc'
go
merge into T1
using (select 1 as ID,'def' as Val1) upd on T1.ID = upd.ID --<-- These identify the row you want to update/insert and the new value you want to set. They could be @parameters
when matched then update set Val1 = upd.Val1
when not matched then insert (ID,Val1) values (upd.ID,upd.Val1);
答案 1 :(得分:1)
您可以使用@@ROWCOUNT并执行UPDATE
。如果受影响的是0行 - 那么之后执行INSERT
,否则就没有了。
答案 2 :(得分:1)
INSERT ... ON DUPLICATE KEY
怎么样?首先进行选择以检查记录是否存在并检查程序结果是否会产生竞争条件。如果只有一个程序实例,那么在你的情况下这可能并不重要。
INSERT INTO users (username, email) VALUES ('Jo', 'jo@email.com')
ON DUPLICATE KEY UPDATE email = 'jo@email.com'
答案 3 :(得分:1)
您的建议意味着每次状态更改始终有两条说明。通常的方法是执行UPDATE,然后检查操作是否更改了任何行(大多数数据库都有一个像ROWCOUNT这样的变量,如果发生了变化,它应该大于0)。如果没有,请执行INSERT。
搜索UPSERT以查找特定DBMS的模式
答案 4 :(得分:1)
就个人而言,我认为UPDATE方法是最好的。您可以先尝试更新UPDATE,但如果没有行受影响(使用@@ ROWCOUNT),您可以先执行SELECT操作,而不是先执行SELECT操作。
原因是您迟早可能想跟踪状态更改,最好的方法是使用状态表上的触发器保留所有更改的审计跟踪。