ALTER TABLE ADD COLUMN takes a long time

后端 未结 3 736
青春惊慌失措
青春惊慌失措 2020-12-02 05:14

I was just trying to add a column called \"location\" to a table (main_table) in a database. The command I run was

ALTER TABLE main_table ADD COLUMN location         


        
相关标签:
3条回答
  • 2020-12-02 05:31

    Your ALTER TABLE statement implies mysql will have to re-write every single row of the table including the new column. Since you have more than 2 million rows, I would definitely expect it takes a significant amount of time, during which your server will likely be mostly IO-bound. You'd usually find it's more performant to do the following:

    CREATE TABLE main_table_new LIKE main_table;
    ALTER TABLE main_table_new ADD COLUMN location VARCHAR(256);
    INSERT INTO main_table_new SELECT *, NULL FROM main_table;
    RENAME TABLE main_table TO main_table_old, main_table_new TO main_table;
    DROP TABLE main_table_old;
    

    This way you add the column on the empty table, and basically write the data in that new table that you are sure no-one else will be looking at without locking as much resources.

    0 讨论(0)
  • 2020-12-02 05:38

    I think the appropriate answer for this is using a feature like pt-online-schema-change or gh-ost.

    We have done migration of over 4 billion rows with this, though it can take upto 10 days, with less than a minute of downtime.

    Percona works in a very similar fashion as above

    • Create a temp table
    • Creates triggers on the first table (for inserts, updates, deletes) so that they are replicated to the temp table
    • In small batches, migrate data
    • When done, rename table to new table, and drop the other table
    0 讨论(0)
  • 2020-12-02 05:39

    Alter table takes a long time with a big data like in your case, so avoid to use it in such situations, and use some code like this one:

    select main_table.*, 
      cast(null as varchar(256)) as null_location, -- any column you want accepts null
      cast('' as varchar(256)) as not_null_location, --any column doesn't accept null
      cast(0 as int) as not_null_int, -- int column doesn't accept null
    into new_table 
    from main_table;
    
    drop table main_table;
    rename table new_table TO main_table;
    
    0 讨论(0)
提交回复
热议问题