OPTIMIZE [LOCAL | NO_WRITE_TO_BINLOG] TABLEtbl_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.
OPTIMIZE TABLE is not supported for
partitioned tables. See
Section 20.3.3, “Maintenance of Partitions”, for information
about alternatives.
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 NDB
Disk Data tables.
In MySQL Cluster NDB 6.3.7 and later MySQL Cluster NDB 6.3
releases, OPTIMIZE TABLE is supported for
dynamic columns of in-memory NDB 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
Previous MySQL Cluster Issues Resolved in MySQL 5.1, 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.
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 |
One of status, error,
info, or warning
|
Msg_text |
The 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 such statements used on a
MySQL server acting as a replication master 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.
This page does not tell you what type of database privileges you need to execute OPTIMIZE TABLES.
You need SELECT and INSERT permissions to optimize a table.
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.
Add your own comment.