如何有效地检查数据库是否包含与挂起插入相同的记录?

时间:2012-02-15 15:43:17

标签: sql sql-server performance indexing

我有一些记录要通过存储过程“插入或更新”到SQL Server数据库中。这些记录具有全局唯一且稳定的ID,以及一堆值属性(大约十二个)。

检查插入是否足够简单 - 查看表中是否存在该键。

假设密钥确实存在,那么我需要检查现有记录是否包含与我传入过程的当前数据完全相同的值。目前我正在通过以下方式这样做:

SELECT @identical = CASE WHEN COUNT(*) > 0 THEN 1 ELSE 0 END FROM Table
    WHERE idCol = @newId
      AND valueCol1 = @newValue1
      AND valueCol2 = @newValue2
      AND ...

这有效,但效率不高;我能够每秒插入大约70条记录,这比我预期的慢很多。

我的第一个想法是添加一个索引 - 但这将几乎索引表中的每一列。这甚至是有道理的还是仅仅是表的第二个副本? (如果相关,则ID列是群集PK。)

有没有明智的方法可以加快必须检查每列值的查询?我正在考虑使用某种哈希来检测重复项,但这会增加一些空间开销,sprocs的复杂性和小的(可接受的)误报的可能性,所以我更倾向于基于索引的解决方案或重写SQL如果一个存在。

3 个答案:

答案 0 :(得分:2)

如果您使用的是SQL Server 2008,则可以使用MERGE语句

答案 1 :(得分:1)

不要事先测试,只要让where-clause为你工作。伪代码(您的语法可能会有所不同)

UPDATE thetable
   SET valueCol1 = @newValue1
     , valueCol2 = @newValue2
     , ...
WHERE idCol = @newId
  AND (valueCol1 <> @newValue1
      OR valueCol2 <> @newValue2
      OR ...
      );

IF (ROWCOUNT > 0) RETURN;

INSERT INTO thetable (idCol, valueCol1, valueCol2, ...)
VALUES (@newId, @newValue1,  @newValue2, ... )
WHERE NOT EXISTS ( SELECT * FROM thetable nx
    WHERE nx.idCol = @newId
    );

答案 2 :(得分:0)

这是一个经典的解决方案

if exists (select * from thetable where idCol = @newID)
begin
    update ....
end
else
begin
   insert ...
end