Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Inserting New Column in MYSQL taking too long

Tags:

mysql

We have a huge database and inserting a new column is taking too long. Anyway to speed up things?

like image 740
Imran Omar Bukhsh Avatar asked Dec 27 '22 14:12

Imran Omar Bukhsh


2 Answers

Unfortunately, there's probably not much you can do. When inserting a new column, MySQL makes a copy of the table and inserts the new data there. You may find it faster to do

CREATE TABLE new_table LIKE old_table;
ALTER TABLE new_table ADD COLUMN (column definition);
INSERT INTO new_table(old columns) SELECT * FROM old_table;
RENAME table old_table TO tmp, new_table TO old_table;
DROP TABLE tmp;

This hasn't been my experience, but I've heard others have had success. You could also try disabling indices on new_table before the insert and re-enabling later. Note that in this case, you need to be careful not to lose any data which may be inserted into old_table during the transition.

Alternatively, if your concern is impacting users during the change, check out pt-online-schema-change which makes clever use of triggers to execute ALTER TABLE statements while keeping the table being modified available. (Note that this won't speed up the process however.)

like image 54
Michael Mior Avatar answered Jan 11 '23 05:01

Michael Mior


There are four main things that you can do to make this faster:

  1. If using innodb_file_per_table the original table may be highly fragmented in the filesystem, so you can try defragmenting it first.

  2. Make the buffer pool as big as sensible, so more of the data, particularly the secondary indexes, fits in it.

  3. Make innodb_io_capacity high enough, perhaps higher than usual, so that insert buffer merging and flushing of modified pages will happen more quickly. Requires MySQL 5.1 with InnoDB plugin or 5.5 and later.

  4. MySQL 5.1 with InnoDB plugin and MySQL 5.5 and later support fast alter table. One of the things that makes a lot faster is adding or rebuilding indexes that are both not unique and not in a foreign key. So you can do this:

A. ALTER TABLE ADD your column, DROP your non-unique indexes that aren't in FKs.

B. ALTER TABLE ADD back your non-unique, non-FK indexes.

This should provide these benefits:

a. Less use of the buffer pool during step A because the buffer pool will only need to hold some of the indexes, the ones that are unique or in FKs. Indexes are randomly updated during this step so performance becomes much worse if they don't fully fit in the buffer pool. So more chance of your rebuild staying fast.

b. The fast alter table rebuilds the index by sorting the entries then building the index. This is faster and also produces an index with a higher page fill factor, so it'll be smaller and faster to start with.

The main disadvantage is that this is in two steps and after the first one you won't have some indexes that may be required for good performance. If that is a problem you can try the copy to a new table approach, using just the unique and FK indexes at first for the new table, then adding the non-unique ones later.

It's only in MySQL 5.6 but the feature request in http://bugs.mysql.com/bug.php?id=59214 increases the speed with which insert buffer changes are flushed to disk and limits how much space it can take in the buffer pool. This can be a performance limit for big jobs. the insert buffer is used to cache changes to secondary index pages.

We know that this is still frustratingly slow sometimes and that a true online alter table is very highly desirable

This is my personal opinion. For an official Oracle view, contact an Oracle public relations person.

James Day, MySQL Senior Principal Support Engineer, Oracle

like image 32
James Day Avatar answered Jan 11 '23 05:01

James Day