我有一个带有自动增量主键的MySql表,似乎所有各种upsert方法(INSERT IGNORE和ON DUPLICATE KEY UPDATE)都受到自动增量字段的呃功能的影响即使行已更新且未插入,也会递增。这意味着在表格中引入了空白,我认为这是不合需要的。
所以问题是:如果upsert实际上只是更新了行,那么有没有办法在带有自动增量字段的表中记录记录而不用自动递增该字段。在我看来,这是upsert应该表现的方式,但它似乎并没有。
答案 0 :(得分:4)
此“问题”仅在InnoDB
。
它是设计用的,旨在提高并发性:另一个线程可以使用AUTO_INCREMENT
而无需等待UPSERT
操作的结果。
来自docs:
服务器启动后,对于第一次插入表
t
,InnoDB
执行此语句的等效语句:SELECT MAX(ai_col) FROM t FOR UPDATE;
<强> ... 强>
使用
InnoDB
初始化但不增加值并将其存储以供以后插入<强> ... 强>
访问自动增量计数器时,
InnoDB
使用一个特殊的表级AUTO-INC
锁,它保持在当前SQL
语句的末尾,而不是结束时交易。引入了特殊的锁定释放策略,以提高插入到包含AUTO_INCREMENT
列的表中的并发性。然而,两个事务不能同时在同一个表上锁定AUTO-INC
,如果长时间保持AUTO-INC
锁定,则会对性能产生影响。对于诸如INSERT INTO t1 ... SELECT ... FROM t2
之类的语句,可能会将所有行从一个表插入另一个表中。
MyISAM
没有出现此行为,因为AUTO_INCREMENT
算法的实现方式不同(由于其支持并发DML
的能力有限)。