批量replace into出现死锁,整体数据中不存在主键相同的数据,唯一索引有两个`name`索引(组合索引:name+source_flag)和index_property2索引(组合索引:id+ property2),其中id是主键。标红的是name和source_flag字段,标绿的是id和property2字段
REPLACE INTO company(id,base,NAME,legal_person_id,legal_person_name,legal_person_type,reg_number,company_type,company_org_type,reg_location,estiblish_time,from_time,to_time,business_scope,reg_institute,approved_time,reg_status,reg_capital,actual_capital,org_number,org_approved_institute,flag,parent_id,updatetime,list_code,ownership_stake,source_flag,name_suffix,property1,property2,property3,property4,property5,crawledtime) 
VALUES('139224108','sd','津津保险公司','25955644','钱司均','1','37040011117153','0','其他股份有限公司分公司(非上市)','山东省枣庄市高新区锦水长街互联网小镇5号楼B座202号','2017-10-25','2017-10-25',NULL,'为投保人拟定投保方案、选择保险人、办理投保手续;协助被保险人或受益人进行索赔;为委托人提供防灾、防损或风险评估、风险管理咨询服务。(依法须经批准的项目,经相关部门批准后方可开展经营活动)','枣庄市工商行政管理局','2017-10-25','在营','','','MA3EQ2TP1','','1','506086','2018-04-01','','','http://qyxy.baic.gov.cn/','','91370400MA3EQ2TP1R','','','','','2017-10-30');REPLACE INTO company(id,base,NAME,legal_person_id,legal_person_name,legal_person_type,reg_number,company_type,company_org_type,reg_location,estiblish_time,from_time,to_time,business_scope,reg_institute,approved_time,reg_status,reg_capital,actual_capital,org_number,org_approved_institute,flag,parent_id,updatetime,list_code,ownership_stake,source_flag,name_suffix,property1,property2,property3,property4,property5,crawledtime) 
VALUES('50207412', 'gd', '潮州市潮安区洁厦瓷业有限公司', '10433735', '蔡映秋', '1', '445121000045309', '0', '有限责任公司(自然人投资或控股)', '潮州市潮安区凤塘镇泮洋村沙堀片', '2000-12-19', '2000-12-19',NULL, '生产:陶瓷卫生洁具、日用瓷、瓷釉(不含危险品及涉及污染物排放)、瓷泥、陶器;销售:水暖器材、不锈钢制品、五金交电、家用电器、塑料制品。(依法须经批准的项目,经相关部门批准后方可开展经营活动)', '广东省潮州市潮安县工商行政管理局', '2018-04-11', '在营(开业)企业', '2000万人民币','', '41741471','', '1', '0', '2018-09-06','','', 'http://qyxy.baic.gov.cn/','', '91445103741741471L','', 'Jiexia Ceramic Industry Co.,Ltd.','','', '2018-09-06')日志截图如下

解决方案 »

  1.   

    replace into 本身就容易引起死锁, 你还搞那么多唯一项, 你要 mysql 按哪个是好?你这种情况, 直接用 update + insert  就是了。
    start transaction;
    update tb set xxx where a=@a and b=@b;
    insert tb select * from( select @a as a, @b as b ) x where row_count()=0;
    commit
      

  2.   

    这是在坑自己,导入到另一个schema下,然后再用语句 insert 多好
      

  3.   


    我用java代码批量提交的时候,试过根据id查询,如果id对于的数据存在则更新,不存在则删除,但是仍然会死锁
      

  4.   


    我用java代码批量提交的时候,试过根据id查询,如果id对于的数据存在则更新,不存在则删除,但是仍然会死锁至少比你现在这样要好吧。
    对于非常繁忙、数据量大的系统, 不适合大表, 不适合太多索引
    id 是主键, 本身就能保证唯一, 还要增加 组合索引:id+ property2 干啥?
    主键一般不要再和其它字段再做索引。你现在的表有多大?另外, 查询最好是:
    SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED ;
    SELECT * FROM TABLE_NAME ;
    COMMIT ;
      

  5.   


    我用java代码批量提交的时候,试过根据id查询,如果id对于的数据存在则更新,不存在则删除,但是仍然会死锁至少比你现在这样要好吧。
    对于非常繁忙、数据量大的系统, 不适合大表, 不适合太多索引
    id 是主键, 本身就能保证唯一, 还要增加 组合索引:id+ property2 干啥?
    主键一般不要再和其它字段再做索引。你现在的表有多大?另外, 查询最好是:
    SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED ;
    SELECT * FROM TABLE_NAME ;
    COMMIT ;表目前数据量没做统计,但是每天更新的数据量比较大,大概一天3-4G左右
      

  6.   


    我用java代码批量提交的时候,试过根据id查询,如果id对于的数据存在则更新,不存在则删除,但是仍然会死锁至少比你现在这样要好吧。
    对于非常繁忙、数据量大的系统, 不适合大表, 不适合太多索引
    id 是主键, 本身就能保证唯一, 还要增加 组合索引:id+ property2 干啥?
    主键一般不要再和其它字段再做索引。你现在的表有多大?另外, 查询最好是:
    SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED ;
    SELECT * FROM TABLE_NAME ;
    COMMIT ;
    关键是这个表不是我们这边的,我没法修改索引