The world's most popular open source database
OPTIMIZE [NO_WRITE_TO_BINLOG | LOCAL] TABLE
tbl_name [, tbl_name] ...
OPTIMIZE TABLE should be used if
you have deleted a large part of a table or if you have made
many changes to a 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.
This statement requires SELECT
and INSERT privileges for the
table.
Beginning with MySQL 5.1.27, OPTIMIZE
TABLE is also supported for partitioned tables. Also
beginning with MySQL 5.1.27, you can use ALTER TABLE
... OPTIMIZE PARTITION to optimize one or more
partitions; for more information, see
Section 12.1.7, “ALTER TABLE Syntax”, and
Section 18.3.3, “Maintenance of Partitions”.
In most setups, you need not run OPTIMIZE
TABLE at all. Even if you do a lot of updates to
variable-length rows, it is not likely that you need to do this
more than once a week or month and only on certain tables.
OPTIMIZE TABLE works
only for MyISAM,
InnoDB, and ARCHIVE
tables. It does not work for tables created
using any other storage engine, including
NDBCLUSTER Disk Data tables.
Beginning with MySQL Cluster NDB 6.3.7,
OPTIMIZE TABLE is supported for
dynamic columns of in-memory NDBCLUSTER
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. See
Section 17.14.11, “Previous MySQL Cluster Issues Resolved in MySQL 5.1 and MySQL Cluster
NDB 6.x”, for more
information.
Beginning with MySQL Cluster NDB 6.3.8,
OPTIMIZE TABLE can be interrupted
by (for example) killing the SQL thread performing the
OPTIMIZE operation.
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.
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. Beginning with MySQL 5.1.27, 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 | +----------+----------+----------+-------------------------------------------------------------------+
You can make OPTIMIZE TABLE work
on other storage engines by starting mysqld
with the --skip-new or
--safe-mode option. In this case,
OPTIMIZE TABLE is just mapped to
ALTER TABLE.
OPTIMIZE TABLE returns a result
set with the following columns:
| Column | Value |
Table |
The table name |
Op |
Always optimize
|
Msg_type |
status, error,
info, or warning
|
Msg_text |
An informational message |
Note that MySQL locks the table during the time
OPTIMIZE TABLE is running.
By default, OPTIMIZE TABLE
statements are written to the binary log so that they will be
replicated to replication slaves. Logging can be suppressed with
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)


User Comments
myisamchk --quick --check-only-changed --sort-index --analyze
do a myisamchk on the table.
--
notice the deleted blocks in the right hand corner of the dialog. The stat still indicates a number > 0 for tables with deleted blocks.
===
myisamchk -r --sort-index --analyze *.MYI fixes that number. I'm inclined to believe the myisamchk *.MYI number since the table I'm "optimizing" does get a lot of deletes.
ALTER TABLE [tbl_name] TYPE=innodb
- will OPTIMIZE an INNODB table in the table space as well
In case you programatically only want to optimize if the data_free (deleted) is some percentage of your data length (size) you can find that out via this statement:
show table status
http://dev.mysql.com/doc/mysql/en/SHOW_TABLE_STATUS.html
Also myisamchk -d has similar.
Don't forget to FLUSH TABLES after execution of any of the following - REPAIR TABLE, TRUNCATE TABLE, OPTIMIZE TABLE, or ANALYZE TABLE on tables that are mapped into MERGE table.
For InnoDB, if you have your tables in one tablespace, this will make a complete copy of the table within the tablespace, making the tablespace larger by the total table size less the free space you started with. It will not reduce the tablespace size. It can free fragmented space within a table to the tablespace, making that space available to other tables. If you're short of disk space and don't want to enlarge the tablespace you may be able to work around this by altering the table to MyISAM and then back to InnoDB.
When using the InnoDB plugin with Barracuda+Compression, issue:
alter table your_table row_format=compressed; to rebuild the table.
Add your own comment.