文档首页
MySQL 9.0 参考手册
相关文档 下载本手册
PDF(US Ltr) - 40.0Mb
PDF(A4) - 40.1Mb
手册页(TGZ) - 258.2Kb
手册页(Zip) - 365.3Kb
Info(Gzip) - 4.0Mb
Info(Zip) - 4.0Mb


MySQL 9.0 参考手册  /  ...  /  OPTIMIZE TABLE 语句

15.7.3.4 OPTIMIZE TABLE 语句

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

OPTIMIZE TABLE 重新组织表数据和相关索引数据的物理存储,以减少存储空间并提高访问表的 I/O 效率。对每个表进行的具体更改取决于该表使用的 存储引擎

根据表的类型,在以下情况下使用 OPTIMIZE TABLE

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

  • 在对包含FULLTEXT索引的InnoDB表执行大量的插入、更新或删除操作后,首先设置配置选项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调整OPTIMIZE在 NDB Cluster 表上的性能,该选项控制OPTIMIZE TABLE处理一批行之间等待的时间长度。有关更多信息,请参见第 25.2.7.11 节,“在 NDB Cluster 9.0 中解决的先前 NDB Cluster 问题”

对于 NDB Cluster 表,可以通过(例如)终止执行OPTIMIZE操作的 SQL 线程来中断OPTIMIZE TABLE

默认情况下,OPTIMIZE TABLE不适用于使用任何其他存储引擎创建的表,并返回一个结果,指示此不支持情况。您可以通过以下方式使OPTIMIZE TABLE适用于其他存储引擎:使用--skip-new选项启动mysqld。在这种情况下,OPTIMIZE TABLE将映射到ALTER TABLE

此语句不适用于视图。

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

默认情况下,服务器将OPTIMIZE TABLE语句写入二进制日志,以便它们复制到副本。要抑制日志记录,请指定可选的NO_WRITE_TO_BINLOG关键字或其别名LOCAL。您必须具有OPTIMIZE_LOCAL_TABLE权限才能使用此选项。

OPTIMIZE TABLE 输出

OPTIMIZE TABLE返回一个结果集,其中包含下表中显示的列。

表名
操作 始终为optimize
消息类型 statuserrorinfonotewarning
消息文本 一条信息性消息

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

InnoDB 详细信息

对于InnoDB表,OPTIMIZE TABLE映射到ALTER TABLE ... FORCE,它会重建表以更新索引统计信息并释放聚簇索引中未使用的空间。当您在InnoDB表上运行它时,这将在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对常规和分区InnoDB表使用在线 DDL,这减少了并发 DML 操作的停机时间。由OPTIMIZE TABLE触发的表重建是在原地完成的。在操作的准备阶段和提交阶段,只会在短暂时间内获取排它表锁。在准备阶段,将更新元数据并创建中间表。在提交阶段,将提交表元数据更改。

OPTIMIZE TABLE在以下情况下使用表复制方法重建表

使用在线 DDLOPTIMIZE TABLE不支持包含FULLTEXT索引的InnoDB表。相反,将使用表复制方法。

InnoDB使用页面分配方法存储数据,不会像传统存储引擎(如MyISAM)那样遭受碎片化。在考虑是否运行优化时,请考虑服务器预期处理的交易工作负载

MyISAM 详细信息

对于MyISAM表,OPTIMIZE TABLE的工作方式如下

  1. 如果表包含已删除或拆分的行,则修复该表。

  2. 如果索引页面未排序,则对其进行排序。

  3. 如果表的统计信息未更新(并且修复无法通过排序索引来完成),则更新这些统计信息。

其他注意事项

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

OPTIMIZE TABLE不会对 R 树索引进行排序,例如对POINT列的空间索引。(错误号 23578)