OPTIMIZE [NO_WRITE_TO_BINLOG | LOCAL] TABLE
tbl_name [, tbl_name] ...
Reorganizes the physical storage of table data and associated index data, to reduce storage space and improve I/O efficiency when accessing the table. The exact changes made to each table depend on the storage engine used by that table. This statement does not work with views.
Use OPTIMIZE TABLE in these
cases, depending on the type of table:
After doing substantial insert, update, or delete operations
on an InnoDB table that has its own
.ibd file because it
was created with the
innodb_file_per_table
option enabled. The table and indexes are reorganized, and
disk space can be reclaimed for use by the operating system.
After deleting a large part of a MyISAM
or ARCHIVE table, or making many changes
to a MyISAM or ARCHIVE
table with variable-length rows (tables that have
VARCHAR,
VARBINARY,
BLOB, or
TEXT columns). Deleted rows
are maintained in a linked list and subsequent
INSERT operations reuse old
row positions. You can use OPTIMIZE
TABLE to reclaim the unused space and to
defragment the data file. After extensive changes to a
table, this statement may also improve performance of
statements that use the table, sometimes significantly.
This statement requires SELECT
and INSERT privileges for the
table.
OPTIMIZE TABLE is also supported
for partitioned tables. For information about using this
statement with partitioned tables and table partitions, see
Section 19.3.3, “Maintenance of Partitions”.
OPTIMIZE TABLE works for
InnoDB,
MyISAM, and
ARCHIVE tables.
OPTIMIZE TABLE is also supported
for dynamic columns of in-memory
NDB tables. It does not work for
Disk Data tables. The performance of OPTIMIZE
on Cluster tables can be tuned by adjusting the value of the
ndb_optimization_delay system variable, which
controls the number of milliseconds to wait between processing
batches of rows by OPTIMIZE
TABLE. For more information, see
Section 18.1.6.11, “Previous NDB Cluster Issues Resolved in MySQL 5.1, NDB Cluster 6.x, and
NDB Cluster 7.x”.
For MySQL Cluster tables, OPTIMIZE
TABLE can be interrupted by (for example) killing the
SQL thread performing the OPTIMIZE operation.
By default, OPTIMIZE TABLE does
not work for tables created using any other
storage engine and returns a result indicating this lack of
support. You can make OPTIMIZE
TABLE work for other storage engines by starting
mysqld with the --skip-new
option. In this case, OPTIMIZE
TABLE is just mapped to ALTER
TABLE.
For InnoDB tables,
OPTIMIZE TABLE is mapped to
ALTER TABLE, which rebuilds the
table to update index statistics and free unused space in the
clustered index. This is displayed in the output of
OPTIMIZE TABLE when you run it on
an InnoDB table, as shown here:
mysql> OPTIMIZE TABLE foo; +----------+----------+----------+-------------------------------------------------------------------+ | Table | Op | Msg_type | Msg_text | +----------+----------+----------+-------------------------------------------------------------------+ | test.foo | optimize | note | Table does not support optimize, doing recreate + analyze instead | | test.foo | optimize | status | OK | +----------+----------+----------+-------------------------------------------------------------------+
This operation does not use fast index creation. Secondary indexes are not created as efficiently because keys are inserted in the order they appeared in the primary key. See Section 14.16.6, “Limitations of Fast Index Creation”.
InnoDB stores data using a page-allocation
method and does not suffer from fragmentation in the same way
that legacy storage engines (such as MyISAM)
will. When considering whether or not to run optimize, consider
the workload of transactions that your server will process:
Some level of fragmentation is expected.
InnoDB only fills
pages 93% full, to leave
room for updates without having to split pages.
Delete operations might leave gaps that leave pages less filled than desired, which could make it worthwhile to optimize the table.
Updates to rows usually rewrite the data within the same page, depending on the data type and row format, when sufficient space is available. See Section 14.12.5, “How Compression Works for InnoDB Tables” and Section 14.14.1, “Overview of InnoDB Row Storage”.
High-concurrency workloads might leave gaps in indexes
over time, as InnoDB retains multiple
versions of the same data due through its
MVCC mechanism. See
Section 14.6, “InnoDB Multi-Versioning”.
For MyISAM tables,
OPTIMIZE TABLE works as follows:
If the table has deleted or split rows, repair the table.
If the index pages are not sorted, sort them.
If the table's statistics are not up to date (and the repair could not be accomplished by sorting the index), update them.
OPTIMIZE TABLE returns a result
set with the following columns.
| Column | Value |
|---|---|
Table | The table name |
Op | Always optimize |
Msg_type | status, error,
info, note, or
warning |
Msg_text | An informational message |
Note that MySQL locks the
table during the time OPTIMIZE
TABLE is running.
By default, the server writes OPTIMIZE
TABLE statements to the binary log so that they
replicate to replication slaves. To suppress logging, specify
the optional NO_WRITE_TO_BINLOG keyword or
its alias LOCAL.
OPTIMIZE TABLE does not sort
R-tree indexes, such as spatial indexes on
POINT columns. (Bug #23578)
As of MySQL 5.5.6, OPTIMIZE TABLE
table catches and throws any errors that occur while copying
table statistics from the old file to the newly created file.
For example. if the user ID of the owner of the
.frm, .MYD, or
.MYI file is different from the user ID of
the mysqld process,
OPTIMIZE TABLE generates a
"cannot change ownership of the file" error unless
mysqld is started by the
root user.