我有一个项目,里面要干这个事:
  1. 数据库里已经有很多记录了 (假设100W条)
  2. 现在客户发来很多新记录 (假设10W条)
  3. 任务很简单: 如果新纪录的ID已存在,做Update; 否则做create。一般的做法是做20W次SQL操作: 
  while(10W次){
    if (记录存在(SQL,新ID){
        update(SQL, 新ID,新数据)
    }else {
        create(SQL, 新ID,新数据)
    }
  }
里面有些细节,比方说10W分成1000条一个batch什么的,先不说了。
请教各位牛人,怎么做能高效一点? 例如只做10W+1次SQLJava DB performance

解决方案 »

  1.   

    首先,看看数据库是否存在一些特殊的SQL语句,可以完成这种更新插入的操作,例如楼上的 merge into 语句其次,如果数据库没有类似功能的语句,一般会先创建一张临时表(表结构与原有表相同)将新数据插入进去,
    之后,通过SQL语句,删除临时表中 与原有表中 相同的数据,
    之后,将临时表中剩余的记录,批量插入到原有表中,
    最后,删除临时表。
    以往经验,数据库的本身数据操作,要不JDBC操作的效率高一些。
    如果采用上述方案,问题瓶颈在于新数据的批量插入操作,想来应该不会太慢。
      

  2.   

    后面的步骤不变。Thank You  ~!
      

  3.   


    我想的和3#差不多。
    1.建个临时表(tmp_client),客户给的全部插进去
    2.update select ..from tmp_client ... where id in (select id from 表名)
    3.insert select ..from tmp_client ... where id not in (select id from 表名)
      

  4.   

    首先感谢各位的回答。 实际验证了一下,回复有点迟了。
    首先试了一楼的merge into, 但是因为这个项目本身使用了OR Mapping的东西,历史原因在插入/update的时候有很多业务逻辑的细节无法用SQL处理,最后只好放弃直接SQL merge的方法了;
    接着像6楼那样,尝试使用存储过程,最后也放弃了,原因有2个:
    1. 首先这个是通用的功能,面临的表很多,每次表做ID的字段也不一样,使用存储过程的话,使用者的配置工作很多,按照公司流程,部署存储过程也很严格,简而言之,实施太复杂了;
    2. 后来发现其实这个事情可以用一条SQL搞定,所以直接用SQL了。
    最后是用SQL做的,思路其实和2/3楼建立临时表的想法是一样的:即挑出create/update的记录。然后还是按照现有流程用OR Mapping的接口创建和update操作。
    因为只是过滤出ID list,而不直接修改/建立数据,所以OR Mapping的东西就没关系了。
    性能改善应该没有1楼的大,但是实际项目,尤其是维护项目往往有各种限制。
    具体的性能提高比例还有待测试。 过两天有结果了,会贴上来并结贴。