Documentation Home
MySQL 8.3 Reference Manual
Related Documentation Download this Manual
PDF (US Ltr) - 40.8Mb
PDF (A4) - 40.9Mb
Man Pages (TGZ) - 294.0Kb
Man Pages (Zip) - 409.0Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb
Excerpts from this Manual

15.7.3.4 OPTIMIZE TABLE 语句

OPTIMIZE [NO_WRITE_TO_BINLOG | LOCAL]
    TABLE tbl_name [, tbl_name] ...

OPTIMIZE TABLE 重新组织表数据和相关索引数据的物理存储,以减少存储空间并提高访问表时的 I/O 效率。每个表的确切变化取决于该表使用的 存储引擎

在以下情况下使用 OPTIMIZE TABLE,具体取决于表的类型:

  • 在对 InnoDB 表进行大量插入、更新或删除操作后,因为它使用了 .ibd 文件,并且启用了 innodb_file_per_table 选项。表和索引将被重新组织,磁盘空间可以被操作系统回收。

  • 在对 InnoDB 表的 FULLTEXT 索引进行大量插入、更新或删除操作后。首先设置配置选项 innodb_optimize_fulltext_only=1。为了保持索引维护期限在合理的时间内,设置 innodb_ft_num_word_optimize 选项以指定要更新的单词数量,然后运行一系列 OPTIMIZE TABLE 语句,直到搜索索引被完全更新。

  • 在删除 MyISAMARCHIVE 表的大部分数据,或者对 MyISAMARCHIVE 表进行了大量更改(具有 VARCHARVARBINARYBLOBTEXT 列)。删除的行将被维护在链表中,后续的 INSERT 操作将重用旧的行位置。可以使用 OPTIMIZE TABLE 回收未使用的空间并碎片数据文件。在对表进行了大量更改后,这个语句也可以提高使用该表的语句的性能,有时性能提高非常明显。

该语句需要 SELECTINSERT 权限来访问该表。

OPTIMIZE TABLE 适用于 InnoDBMyISAMARCHIVE 表。OPTIMIZE TABLE 也支持内存中的 NDB 表的动态列。它不适用于固定宽度列的内存表,也不适用于磁盘数据表。可以使用 --ndb-optimization-delay 选项来调整 NDB Cluster 表上的 OPTIMIZE 性能。有关更多信息,请参阅 第 25.2.7.11 节,“NDB Cluster 8.0 中解决的以前的问题”

对于 NDB Cluster 表,OPTIMIZE TABLE 可以被(例如)杀死执行 OPTIMIZE 操作的 SQL 线程所中断。

默认情况下,OPTIMIZE TABLE 不适用于使用其他存储引擎创建的表,并返回一个结果,表明缺乏支持。你可以通过启动 mysqld with the --skip-new 选项,使 OPTIMIZE TABLE 适用于其他存储引擎。在这种情况下,OPTIMIZE TABLE 只是映射到 ALTER TABLE

该语句不适用于视图。

OPTIMIZE TABLE 支持分区表。有关使用该语句与分区表和表分区的信息,请参阅 第 26.3.4 节,“分区维护”

默认情况下,服务器将 OPTIMIZE TABLE 语句写入二进制日志,以便复制到副本。要抑制日志记录,请指定可选的 NO_WRITE_TO_BINLOG 关键字或其别名 LOCAL

OPTIMIZE TABLE 输出

OPTIMIZE TABLE 返回一个结果集,具有以下表中的列。

Column Value
表名
Op 始终 optimize
Msg_type 状态错误信息注意警告
Msg_text 信息性消息

OPTIMIZE TABLE 捕获并抛出在从旧文件复制表统计信息到新创建的文件时发生的任何错误。例如,如果 .MYD.MYI 文件的所有者用户 ID 与 mysqld 进程的用户 ID 不同,OPTIMIZE TABLE 生成“无法更改文件所有权”错误,除非 mysqld 由根用户启动。

InnoDB 详情

对于 InnoDB 表,OPTIMIZE TABLE 映射到 ALTER TABLE ... FORCE,该语句重建表以更新索引统计信息和释放聚簇索引中的未使用空间。这将在 OPTIMIZE TABLE 的输出中显示,如下所示:

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                                                                |
+----------+----------+----------+-------------------------------------------------------------------+

OPTIMIZE TABLE 使用 在线 DDL 对常规和分区的 InnoDB 表,减少了并发 DML 操作的停机时间。由 OPTIMIZE TABLE 触发的表重建是在原地完成的。在准备阶段和提交阶段,仅briefly 获取独占表锁。在准备阶段,元数据被更新,并创建了中间表。在提交阶段,表元数据更改被提交。

OPTIMIZE TABLE 在以下情况下使用表副本方法重建表:

OPTIMIZE TABLE 使用 在线 DDL 不支持包含 FULLTEXT 索引的 InnoDB 表。相反,使用表副本方法。

InnoDB 使用页分配方法存储数据,不像遗留存储引擎(如 MyISAM)那样遭受碎片化。当考虑是否运行 optimize 时,考虑服务器预期处理的事务工作负载:

MyISAM 详情

对于 MyISAM 表,OPTIMIZE TABLE 按照以下方式工作:

  1. 如果表中有已删除或拆分的行,修复表。

  2. 如果索引页未排序,排序它们。

  3. 如果表的统计信息不最新(且无法通过排序索引来修复),更新它们。

其他考虑因素

OPTIMIZE TABLE 对常规和分区的 InnoDB 表在线执行。否则,MySQL 在 OPTIMIZE TABLE 运行期间锁定表。

OPTIMIZE TABLE 不对 R-tree 索引(如 POINT 列上的空间索引)进行排序。(Bug #23578)