SQL唯一:手动检查与捕获异常

时间:2014-10-18 15:55:15

标签: sql unique

我正在开发一个大型数据库,我正在寻找可以加快数据库速度的一切。问题是:当你在某些字段上有一个唯一索引时,选择一个请求检查它是否正常,或者无论如何都要尝试并在条目已经存在时捕获异常之间的速度是多快?

我做了一些研究,但没有结论。感谢。

3 个答案:

答案 0 :(得分:4)

手动检查不会做你认为它做的事情。 (见下文。)

如果先检查,每个插入都需要两次往返数据库。它可能还需要可序列化的事务。

无论如何你必须陷入错误。重复值只是一个在插入时可能出错的东西;还有其他可能出错的很多

我说只是插入并捕获错误。


INSERT之前的SELECT点是确定数据库中是否已存在某个值。但你不能依靠它来工作。这就是原因。

打开两个终端会话(例如),并将它们连接到您的数据库。该表已存在。它是空的。

create table test (
  test_id serial primary key, 
  test_email varchar(15) not null unique
);
A: begin transaction;
A: select test_email 
   from test 
   where test_email = 'a@b.com';
   (0 rows)

                                       B: begin transaction;

A: insert into test (test_email) 
   values ('a@b.com');
   INSERT 0 1

                                       B: select test_email 
                                          from test 
                                          where test_email = 'a@b.com';
                                          (0 rows)
                                       B: insert into test (test_email) 
                                          values ('a@b.com');
                                          (waiting for lock)

A: commit;

                                       B: ERROR:  duplicate key value 
                                          violates unique constraint...

答案 1 :(得分:3)

你有两个选择

  1. 尝试插入,如果查询失败,您将捕获并回滚事务。
  2. 尝试查询一次以检查它是否存在。如果它不存在,请插入值。
  3. 在我看来,第一个更好,因为如果你查询两次你使用网络连接两次。当您拥有非常大的数据时,select也是一个不错的选择。 在第一种情况下,您尝试插入但得到DataIntegrityException。单个请求和响应优于两个请求和两个响应。

    事务管理器也可以处理异常。

答案 2 :(得分:1)

我的理解是try / catch异常会突然停止程序的流程。即使处理得当。建议的做法是将它们与域逻辑分开使用。除非您的数据库服务器距离很远,否则额外的选择不应该那么糟糕。