不断尝试插入现有键值是不好的做法

时间:2013-12-06 14:39:43

标签: java sql oracle entity-relationship

我很想知道以下两个细节。

  1. 它是否被认为是不好的做法,或者是连续尝试插入重复数据并允许dbms强制执行实体的约束以拒绝这些插入的最差性能。或者最好做一些SELECT COUNT(1),只有在count不是1的情况下插入。

  2. 假设从第一个项目开始,从dbms透视图强制实施实体的约束并且不进行多次调用会更有效。由于代码不必要地进入异常块,即使不处理异常,应用程序代码(Java,.NET等)是否会受到更大的性能影响。

  3. 可能重复:Inserting data into SQL Table with Primary Key. For dupes - allow insert error or Select first?

4 个答案:

答案 0 :(得分:5)

就性能而言,最好使用数据库内功能来强制执行约束。

当您尝试在数据库外部强制执行约束时,您有两个问题。第一个是你有运行单独查询,返回结果和执行逻辑 - 几个数据库操作的开销。另一方面,使用约束可能会做同样的工作,但它在数据库中完成所有操作,而没有额外的来回传递事务的开销。

其次,当您尝试自己强制执行约束时,会引入竞争条件。这意味着您可以运行count()并返回0.同时,另一个事务插入值,然后插入失败。你真的想避免这种竞争条件。当然,一种解决方案是将所有逻辑放在单个事务中。这引入了自己的开销。

答案 1 :(得分:1)

如果你需要做一个选择,然后每次插入都要慢得多,因为它需要两次往返。检查异常的成本与执行数据库语句所需的时间无关。

某些数据库允许“upsert”语句,如果它不作为一个调用存在,则允许您同时执行更新然后插入。

如果你这么做很多,你需要退一步思考整体算法和架构。为什么你不断尝试插入已经存在的值,并且有些东西你可以改变它们根本不会发生 - 而不是在数据库点处理失败。

答案 2 :(得分:0)

只是你增​​加了往返时间。一次检查和其他时间插入,如果不重复。 可能是不好的。但是,首先检查然后插入和捕获catch exception and handle it之间time comparisonException的情况有很大不同。

修改 第一次检查可能会出现一个问题,然后插入是synchronization。可能是某些线程更新/在您检查到没有重复的情况下在线程之前插入数据,结果将在结尾处异常。所以你必须解决不能离开的问题。

答案 3 :(得分:0)

就个人而言,我可能会写一个光标来检查记录是否存在。对我来说,这是一种更简洁的方法,而不是依赖于异常来控制程序流程。是的,有性能影响,但很可能是微不足道的。干净,可读的代码将优先考虑我。