这是一种常见的情况,但是我想找出性能优化的方法和最佳实践

我有一个包含4列的表格:id,name和其他两个字段。 Id是PK,名称是唯一键。我正在从excel文件中读取数据,在Domain对象中填充每一行的值,然后将其保存。保存时,我想查看是否已存在相同名称的记录,如果存在,我想更新它。否则将其另存为新记录。

我可以使用普通的select查询来做到这一点,并检查是否为空,并基于该插入或更新进行操作,但是我有数千行要从excel文件中读取,并且要求的非功能性要求是性能

因此,请向我提出建议,以哪种方式最好地处理此senario?我尚未开始对持久层部分进行编码,因此我可以根据您的建议切换到ORM或纯jdbc。

编辑:
如果我使用名称作为主键,那么我认为我可以使用saveOrUpdate或从ORM进行合并来满足我的需求。这是不是一个好主意???
感谢和问候,
Prasath。

最佳答案

我认为最快的方法是在数据库本身中执行所有插入/更新,而不是连接到数据库并使用大量语句。

注意,这是特定于Oracle的,但是其他数据库可能具有类似的概念。

我将使用以下方法:首先将Excel数据作为CSV文件保存在数据库服务器上(/mydatadir/mydata.csv),然后在Oracle中,我将使用external table:

create or replace directory data_dir as '/mydatadir/';
create table external_table (
  id number(18),
  name varchar2(30),
  otherfield1 varchar2(40),
  otherfield2 varchar2(40))
organization external (
  type oracle_loader
  default directory data_dir
  access parameters
  ( fields terminated by ',' )
  location ('mydata.csv')
)

(请注意,不必每次都设置外部表)

然后,您可以使用以下命令将数据merge到表中:
merge into yourtable t
using external_table e
on t.name = e.name
when matched then
   update set t.id = e.id,
              t.otherfield1 = e.otherfield1,
              t.otherfield2 = t.otherfield2
when not matched then
   insert (t.id, t.name, t.otherfield1, t.otherfield2)
   values (e.id, e.name, e.otherfield1, e.otherfield2)

这将在一个Oracle命令中将yourtable中的行向上插入,因此所有工作将由数据库执行。

编辑:

可以通过纯JDBC发出merge命令(尽管我更喜欢使用Spring的SimpleJdbcTemplate)

编辑2:

在MySQL中,您可以使用以下结构执行合并:
insert into yourtable (id, name, otherfield1, otherfield2)
values (?, ?, ?, ?),
       (?, ?, ?, ?),
       (?, ?, ?, ?) --repeat for each row in the Excel sheet...
on duplicate Key update
set otherfield1 = values(otherfield1),
    otherfield2 = values(otherfield2)

这可以作为普通的JDBC语句发布,并且比单独的更新和插入要好,并且可以从电子表格中批量调用(例如)一百行。这意味着Excel工作表中每100行有1个JDBC调用,并且应该表现良好。这样就可以在没有外部表的情况下进行操作(您需要在name列上使用UNIQUE索引才能正常工作,我不会更改主键,因为如果需要更改,这可能会导致外键出现问题某人的名字)。

MySQL还具有external tables的概念,我认为它比按上述批量插入数据还要快。只要将csv文件上传到正确的位置,导入就可以快速进行。

09-25 18:25
查看更多