MySql upsert和auto-increment会导致间隙

时间:2010-09-09 18:47:38

标签: mysql upsert

我有一个带有自动增量主键的MySql表,似乎所有各种upsert方法(INSERT IGNORE和ON DUPLICATE KEY UPDATE)都受到自动增量字段的呃功能的影响即使行已更新且未插入,也会递增。这意味着在表格中引入了空白,我认为这是不合需要的。

所以问题是:如果upsert实际上只是更新了行,那么有没有办法在带有自动增量字段的表中记录记录而不用自动递增该字段。在我看来,这是upsert应该表现的方式,但它似乎并没有。

1 个答案:

答案 0 :(得分:4)

此“问题”仅在InnoDB

它是设计用的,旨在提高并发性:另一个线程可以使用AUTO_INCREMENT而无需等待UPSERT操作的结果。

来自docs

  

服务器启动后,对于第一次插入表tInnoDB执行此语句的等效语句:

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的能力有限)。