MySQL: Why does my INSERT statement skip 56 numbers when auto-incrementing the id?

后端 未结 1 997
礼貌的吻别
礼貌的吻别 2020-12-21 08:03

While demonstrating the INSERT statement to the students of my SQL course, we\'ve come up on some odd behavior in MySQL 8.0. Please help us learn what is happenning. (No nee

相关标签:
1条回答
  • 2020-12-21 09:04

    This behavior has something to do with "bulk inserts" and the innodb_autoinc_lock_mode setting.

    As far as I understand it (the documentation isn't quite clear about this), when you use a INSERT INTO ... SELECT statement, MySQL cannot know how many rows are actually being inserted before running the query, but the IDs for the new AUTO_INCREMENT values have to be reserved when using innodb_autoinc_lock_mode=1 (consecutive) or 2 (interleaved). From my observation it reserves a set of AUTO_INCREMENT numbers where the count is a power of 2 (cannot confirm this, only a guess). See the following example:

    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;
    

    This will generate the following output:

    +----+----------+
    | id | original |
    +----+----------+
    |  1 | one      |
    |  2 | two      |
    |  3 | three    |
    |  4 | four     |
    |  5 | five     |
    |  8 | manual   |
    +----+----------+
    

    When inserting the 5 rows from the source table, it reserves the next 8 possible AUTO_INCREMENT values because that is the closest power of 2 number greater than 5. However, it will use only 5 of them since you insert only 5 rows.

    In your case, you are inserting 200 rows, so the closest power of 2 number greater than 200 would be 256. So you have a "gap" of 56 missing AUTO_INCREMENT values and the next entry gets the ID 256.

    0 讨论(0)
提交回复
热议问题