为什么自动增量跳跃的行数超过插入的行数?

Que*_*low 14 mysql innodb mariadb auto-increment

auto_increment在使用存储过程执行批量插入后,我在 Bids 表的 bidID 中记录的值中看到了这种奇怪的行为,我感到非常不安:

INSERT INTO Bids (itemID, buyerID, bidPrice)
 SELECT itemID, rand_id(sellerID, user_last_id), FLOOR((1 + RAND())*askPrice)
 FROM Items
 WHERE closing BETWEEN NOW() AND NOW() + INTERVAL 1 WEEK ORDER BY RAND() LIMIT total_rows;
Run Code Online (Sandbox Code Playgroud)

例如,如果开始时的auto_incrementbidID 值为 101,并且我插入了 100 行,则结束值变为 213 而不是 201。但是,这些插入行的 bidID 依次运行,最多为 201。

检查以下内容后,

SHOW VARIABLES LIKE 'auto_inc%';
+--------------------------+-------+
| Variable_name            | Value |
+--------------------------+-------+
| auto_increment_increment | 1     |
| auto_increment_offset    | 1     |
+--------------------------+-------+
Run Code Online (Sandbox Code Playgroud)

我不知道为什么会这样。什么可能导致auto increment价值的跳跃?

Dav*_*ett 11

这并不罕见,有几个原因。有时这是由于查询运行程序进行了优化以减少计数器资源的争用问题,从而在对受影响的表进行并发更新时提高效率。有时是由于事务显式回滚(或由于遇到错误而隐式回滚)。

auto_increment列(或IDENTITY在 MSSQL 中,以及概念所涉及的其他名称)的唯一保证是每个值都将是唯一的并且永远不会小于前一个值:因此您可以依赖这些值进行排序,但您不能依赖他们没有差距。

如果您需要列的值完全没有间隙,您将需要自己管理这些值,无论是在另一层业务逻辑中还是通过触发器在数据库中(但请注意触发器的潜在性能问题),当然,如果您确实自己动手,您将不得不应对数据库引擎通过允许间隙解决的所有并发/回滚/删除后清理/其他问题)。

  • 查看 MySQL 的详细信息:[AUTO_INCREMENT Handling in InnoDB](http://dev.mysql.com/doc/refman/5.6/en/innodb-auto-increment-handling.html),其中提到:*"** “批量插入”** 的自动增量值中的差距 ... 对于锁定模式 1 或 2,连续语句之间可能会出现差距,因为对于批量插入,每个语句所需的自动增量值的确切数量可能未知,并且高估是可能的。”* (4认同)