在插入之前检查主键值是否比使用try-catch更快?

时间:2011-03-16 20:40:54

标签: sql-server performance sql-server-2008

基本上我有一个带有双字段主键列(memberid,messageid)的表,我有一个存储过程,在该表中插入一个新行。

现在我检查是否存在具有PK的行,如果没有则插入,但是在检查后和实际插入之前由不同进程插入行时我已经遇到过这种情况,所以我想到另一种方式。

出于性能原因,我不想使用事务,所以我想把INSERT放入try-catch并完全跳过检查。如果该行已存在,则insert将失败,但将被“catch”静音,这是正常的。

我的问题是 - 抛出一个错误并将其捕获到昂贵的操作中?

4 个答案:

答案 0 :(得分:3)

在SQL 2008上,您可以使用MERGE - 比您的任何一种方法都简单得多。

此外,我并不是因为“我不想出于性能原因而使用事务” - 您执行的每个DML命令都是某个事务的一部分,所以即使您没有显式打开它们也会有事务。如果您遇到性能问题,可以发布更多详细信息,以便获得更多性能方面的帮助。

编辑:如果您需要快速插入,请不要一次插入一行。添加行集,并使用MERGE - 从一次插入批量行中获得的优势应该远远超过通过优化添加行的速度获得的任何微小改进。

无论如何,关于与数据库相关的任何事情的理论推理通常都不够好。您真的需要进行基准测试以确定哪些更快。您所谓的“对现有线路进行不必要的查询”可能完全可以忽略不计,在您在实际条件下进行测量之前,您不知道是否属于这种情况。

答案 1 :(得分:0)

是的,抛出异常是一项昂贵的操作。但是,它可能是应用程序特定的,但吞咽(沉默,如你所说)的例外通常不是一个好主意。

答案 2 :(得分:0)

如果您不希望失败经常发生,那么可以通过例外处理它。

每次进行检查都会降低数据库性能,这也会影响应用性能......

答案 3 :(得分:0)

如果您没有使用事务,则必须考虑是否可能插入行,因此您无法消除异常处理。最好通过事先进行查询来最小化罕见异常。但是,在每个插入之前执行查询的成本可能会超过偶然的异常。

你必须自己测试一下,看看现实生活中哪些东西更贵。可能的是,偶尔异常的成本毫秒将远远低于不断查询即将插入的密钥的成本。

也就是说,您可以使用存储过程来处理插入并在插入重复键时返回错误值而不是抛出异常。这应该完全消除性能问题。