15

我正在测试插入选择查询并注意到一个奇怪的结果。

CREATE TABLE `test` (
  `cnt` int(11) NOT NULL AUTO_INCREMENT,
  `a` int(11) DEFAULT NULL,
  `b` int(11) DEFAULT NULL,
  PRIMARY KEY (`cnt`)
)

CREATE TABLE `test_current` (
  `a` int(11) DEFAULT NULL,
  `b` int(11) DEFAULT NULL
)

首先我创建了两个表,并将一些值插入到 test_current

mysql> insert into test_current (a,b) values (1,1),(2,2);
Query OK, 2 rows affected (0.00 sec)
Records: 2  Duplicates: 0  Warnings: 0

我做了这个查询

mysql> INSERT INTO test (a,b) SELECT a,b FROM test_current;
Query OK, 2 rows affected, 1 warning (0.00 sec)
Records: 2  Duplicates: 0  Warnings: 1

mysql> select * from test;
+-----+------+------+
| cnt | a    | b    |
+-----+------+------+
|   1 |    1 |    1 |
|   2 |    2 |    2 |
+-----+------+------+
2 rows in set (0.00 sec)

但是当我再次查询时

mysql> INSERT INTO test (a,b) SELECT a,b FROM test_current;
Query OK, 2 rows affected, 1 warning (0.00 sec)
Records: 2  Duplicates: 0  Warnings: 1

mysql> select * from test;
+-----+------+------+
| cnt | a    | b    |
+-----+------+------+
|   1 |    1 |    1 |
|   2 |    2 |    2 |
|   4 |    1 |    1 |
|   5 |    2 |    2 |
+-----+------+------+

自动增量只是跳过了 cnt 3。我想知道这是怎么回事。

4

3 回答 3

2

您可以在每次将值插入表之前将 auto_increment 值重置为 1:

ALTER TABLE `test` AUTO_INCREMENT = 1;
INSERT INTO test (a,b) SELECT a,b FROM test_current;
于 2012-09-01T08:37:47.703 回答
2

您可以从my.ini更改 innodb_autoinc_lock_mode=0(“传统”锁定模式)以避免在某些情况下跳过主键中的值。有关更多详细信息,请参阅手动mysql 手册以了解 innodb 自动增量处理

根据手册“提供传统锁定模式选项是为了向后兼容性、性能测试以及解决“混合模式插入”的问题,因为语义上可能存在差异。

'在这种锁定模式下,所有“INSERT-like”语句都获得一个特殊的表级 AUTO-INC 锁,用于插入具有 AUTO_INCREMENT 列的表。此锁通常保持到语句的末尾(而不是事务的末尾),以确保为给定的 INSERT 语句序列以可预测和可重复的顺序分配自动递增值,并确保自动递增任何给定语句分配的值都是连续的。

要检查的另一件事是 auto_increment_increment 配置变量的值。默认情况下为 1,但您可能已更改此值。将其设置为高于 1 或 2 的值非常罕见,但有可能。

或者,如果它在您的情况下不起作用,您也可以在同一页面中使用 AnandPhadke 的答案之类的查询,例如:

ALTER TABLE 表名 AUTO_INCREMENT = 1;
插入表名 (col1,col2,col3) 从表名中选择 col1,col2,col3;

于 2018-07-27T08:04:02.360 回答
1

放入你的 My.cnf:

innodb_autoinc_lock_mode=0
于 2014-10-02T12:12:17.563 回答