Hành vi này có liên quan đến " số lượng lớn chèn "
và innodb_autoinc_lock_mode
cài đặt.
Theo như tôi hiểu (tài liệu không rõ ràng về điều này), khi bạn sử dụng INSERT INTO ... SELECT
tuyên bố, MySQL không thể biết có bao nhiêu hàng thực sự đang được chèn trước khi chạy truy vấn, nhưng ID cho các giá trị AUTO_INCREMENT mới phải được đặt trước khi sử dụng innodb_autoinc_lock_mode=1
(liên tiếp) hoặc 2
(xen kẽ). Từ quan sát của tôi, nó dự trữ một bộ số AUTO_INCREMENT trong đó số đếm là lũy thừa của 2 (không thể xác nhận điều này, chỉ là phỏng đoán). Xem ví dụ sau:
CREATE TABLE sourceTable(
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(20)
);
CREATE TABLE targetTable(
id INT AUTO_INCREMENT PRIMARY KEY,
original VARCHAR(30)
);
INSERT INTO sourceTable(name) VALUES ('one');
INSERT INTO sourceTable(name) VALUES ('two');
INSERT INTO sourceTable(name) VALUES ('three');
INSERT INTO sourceTable(name) VALUES ('four');
INSERT INTO sourceTable(name) VALUES ('five');
INSERT INTO targetTable(original) SELECT name FROM sourceTable;
INSERT INTO targetTable(original) VALUES ('manual');
SELECT * FROM targetTable;
Điều này sẽ tạo ra kết quả sau:
+----+----------+
| id | original |
+----+----------+
| 1 | one |
| 2 | two |
| 3 | three |
| 4 | four |
| 5 | five |
| 8 | manual |
+----+----------+
Khi chèn 5 hàng từ bảng nguồn, nó dự trữ 8 giá trị AUTO_INCREMENT tiếp theo có thể có vì đó là lũy thừa gần nhất của 2 số lớn hơn 5. Tuy nhiên, nó sẽ chỉ sử dụng 5 trong số đó vì bạn chỉ chèn 5 hàng.
Trong trường hợp của bạn, bạn đang chèn 200 hàng, vì vậy lũy thừa gần nhất của 2 số lớn hơn 200 sẽ là 256. Vì vậy, bạn có một "khoảng cách" 56 giá trị AUTO_INCREMENT bị thiếu và mục nhập tiếp theo nhận được ID 256.