mysql DUPLICATE KEY UPDATE 问题
DUPLICATE KEY UPDATE batch执行时出死锁错误
背景知识
一、 mysql insert 与 duplicate key:
典型的插入语句:
多条:INSERT INTO tablename (columnA, columnB, columnC)
VALUES ('a', 1, 2), ('b', 7, 5)
单条:INSERT INTO tablename SET columnA='a', columnB=1, columnC=2
复制:INSERT [options1] [INTO] tablename [ (columnlist) ] SELECT …
若表已设置主键如columnA,重复的插入无效
ERROR 1062 (23000): Duplicate entry 'value' for key 'PRIMARY'
如果数据库中已有某条数据,以下的两条语句可等同:
INSERT INTO tablename (id, data) VALUES (1, 10)
ON DUPLICATE KEY UPDATE data=data+10;
UPDATE tablename SET data=data+10 WHERE id=1;
duplicate key语句一般应用在 格式化多条更新语句:
INSERT INTO tablename (id, data) VALUES (1, 10), (2, 15) ON DUPLICATE KEY UPDATE data=data+VALUE(data)
二、innodb表提高插入效率
查询表使用的引擎: show create table tablename;
innodb 的存储引擎提供行级锁,支持共享锁和排他锁两种锁定模式,以及四种不同的隔离级别。
对于Innodb 类型的表,我们有以下几种方式可以提高导入的效率: a. 因为Innodb 类型的表是按照主键的顺序保存的,所以将导入的数据按照主键的顺 序排列,可以有效的提高导入数据的效率。如果Innodb 表没有主键,那么系统会默认 创建一个内部列作为主键,所以如果可以给表创建一个主键,将可以利用这个优势提高 导入数据的效率。 b. 在导入数据前执行SET UNIQUE_CHECKS=0,关闭唯一性校验,在导入结束后执行SET UNIQUE_CHECKS=1,恢复唯一性校验,可以提高导入的效率。 c. 如果应用使用自动提交的方式,建议在导入前执行SET AUTOCOMMIT=0,关闭自动 提交,导入结束后再执行SET AUTOCOMMIT=1,打开自动提交,也可以提高导入的效率。
如果如果你同时从同一客户插入很多行,使用多个值表的INSERT 语句。这比使用分开INSERT 语句快(在一些情况中几倍)。
你从不同客户插入很多行,能通过使用INSERT DELAYED 语句得到更高的速度。Delayed 的含义是让insert 语句马上执行,其实数据都被放在内存的队列中,并没有真正写入磁盘;这比每条语句分别插入要快的多;LOW_PRIORITY 刚好相反,在所有其他用户对表的读写完后才进行插入;
在项目中遇到的问题时,使用了这种insert处理,但是分库分表,数据表类型为innodb, tablename各不相同,duplicate key只是用于合并update和insert语句。
"java.sql.BatchUpdateException: Deadlock found when trying to get lock; try restarting transaction" 错误状况为 第一个插入即出错,或一个batch中重复一个key,插入多个值。 貌似mysql有这个bug(http://bugs.mysql.com/bug.php?id=52020)
使用threadlocal去获取操作数据库的对象,static对象,获取pool的连接并执行批处理方法
PRIMARY KEY
UNIQUE KEY 的区别
- 关于 MySQL UTF8 编码下生僻字符插入失败/假死问题的分析
- Windows用户自查:微软紧急更新修复Meltdown和Spectre CPU漏洞
- rsync error: protocol incompatibility / mismatch
- 玩转 SHELL 脚本之:Shell 命令 Buffer 知多少?
- 使用实体嵌入的结构化数据进行深度学习
- CoffeeMiner:劫持WiFi网络接入设备进行“挖矿”的框架
- 数码管显示电路的Verilog HDL 实现
- 超前进位加法器
- 使用腾讯云“自定义监控”监控 GPU 使用率
- 非整数分频模块
- 偶数倍频
- Fiddler 高级用法:Fiddler Script 与 HTTP 断点调试
- Spark 伪分布式 & 全分布式 安装指南
- 十步完全理解 SQL
- MySQL 教程
- MySQL 安装
- MySQL 管理与配置
- MySQL PHP 语法
- MySQL 连接
- MySQL 创建数据库
- MySQL 删除数据库
- MySQL 选择数据库
- MySQL 数据类型
- MySQL 创建数据表
- MySQL 删除数据表
- MySQL 插入数据
- MySQL 查询数据
- MySQL where 子句
- MySQL UPDATE 查询
- MySQL DELETE 语句
- MySQL LIKE 子句
- mysql order by
- Mysql Join的使用
- MySQL NULL 值处理
- MySQL 正则表达式
- MySQL 事务
- MySQL ALTER命令
- MySQL 索引
- MySQL 临时表
- MySQL 复制表
- 查看MySQL 元数据
- MySQL 序列 AUTO_INCREMENT
- MySQL 处理重复数据
- MySQL 及 SQL 注入
- MySQL 导出数据
- MySQL 导入数据
- MYSQL 函数大全
- MySQL Group By 实例讲解
- MySQL Max()函数实例讲解
- mysql count函数实例
- MYSQL UNION和UNION ALL实例
- MySQL IN 用法
- MySQL between and 实例讲解