#### 13.7.3.4 OPTIMIZE TABLE 语句

[](<>)[](<>)[](<>)

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

[`优化表`](optimize-table.html)重组表数据和关联索引数据的物理存储，减少存储空间，提高访问表时的I/O效率。对每个表所做的确切更改取决于[存储引擎](glossary.html#glos_storage_engine)该表使用。

采用[`优化表`](optimize-table.html)在这些情况下，取决于表的类型：

-   在对一个对象执行大量插入、更新或删除操作后`InnoDB`有自己的表[.ibd 文件](glossary.html#glos_ibd_file)因为它是用[`innodb_file_per_table`](innodb-parameters.html#sysvar_innodb_file_per_table)选项启用。重新组织表和索引，并且可以回收磁盘空间以供操作系统使用。

-   在对属于`全文`中的索引`InnoDB`桌子。设置配置选项[`innodb_optimize_fulltext_only=1`](innodb-parameters.html#sysvar_innodb_optimize_fulltext_only)第一的。要将索引维护期保持在合理的时间，请设置[`innodb_ft_num_word_optimize`](innodb-parameters.html#sysvar_innodb_ft_num_word_optimize)选项指定要在搜索索引中更新多少单词，并运行一系列`优化表`语句，直到搜索索引完全更新。

-   删除大部分内容后`MyISAM`要么`档案`表，或对一个表进行许多更改`MyISAM`要么`档案`具有可变长度行的表（具有[`VARCHAR`](char.html),[`变量`](binary-varbinary.html),[`斑点`](blob.html)， 要么[`文本`](blob.html)列）。删除的行保存在链表中，随后[`插入`](insert.html)操作重用旧的行位置。您可以使用[`优化表`](optimize-table.html)回收未使用的空间并对数据文件进行碎片整理。在对表进行大量更改后，此语句还可以提高使用该表的语句的性能，有时会显着提高。

    该声明要求[`选择`](privileges-provided.html#priv_select)和[`插入`](privileges-provided.html#priv_insert)表的特权。

[`优化表`](optimize-table.html)效劳于[`InnoDB`](innodb-storage-engine.html),[`MyISAM`](myisam-storage-engine.html)， 和[`档案`](archive-storage-engine.html)表。[`优化表`](optimize-table.html)也支持内存中的动态列[`新开发银行`](mysql-cluster.html)表。它不适用于内存表的固定宽度列，也不适用于磁盘数据表。的表现`优化`在 NDB Cluster 表上可以使用[`--ndb-优化-延迟`](mysql-cluster-options-variables.html#option_mysqld_ndb-optimization-delay)，它控制在处理批次行之间等待的时间长度[`优化表`](optimize-table.html).有关详细信息，请参阅[第 23.2.7.11 节，“NDB Cluster 8.0 中解决的以前的 NDB Cluster 问题”](mysql-cluster-limitations-resolved.html).

对于 NDB Cluster 表，[`优化表`](optimize-table.html)可以通过（例如）杀死执行`优化`手术。

默认，[`优化表`](optimize-table.html)做*不是*为使用任何其他存储引擎创建的表工作，并返回表明缺乏支持的结果。你（们）能做到[`优化表`](optimize-table.html)通过启动为其他存储引擎工作[**mysqld**](mysqld.html)与[`--skip-new`](server-options.html#option_mysqld_skip-new)选项。在这种情况下，[`优化表`](optimize-table.html)只是映射到[`更改表`](alter-table.html).

此语句不适用于视图。

[`优化表`](optimize-table.html)支持分区表。有关将此语句与分区表和表分区一起使用的信息，请参阅[第 24.3.4 节，“分区维护”](partitioning-maintenance.html).

默认情况下，服务器写入[`优化表`](optimize-table.html)对二进制日志的语句，以便它们复制到副本。要禁止记录，请指定可选的`NO_WRITE_TO_BINLOG`关键字或其别名`当地的`.

-   [优化表输出](optimize-table.html#optimize-table-output)

-   [InnoDB 详细信息](optimize-table.html#optimize-table-innodb-details)

-   [MyISAM 详细信息](optimize-table.html#optimize-table-myisam-details)

-   [其他注意事项](optimize-table.html#optimize-table-other-considerations)

##### 优化表输出

[`优化表`](optimize-table.html)返回具有下表所示列的结果集。

| 柱子 | 价值 |
| --- | --- |
| `桌子` | 表名 |
| `操作` | 总是`优化` |
| `消息类型` | `状态`,`错误`,`信息`,`笔记`， 要么`警告` |
| `消息文本` | 信息性消息 |

[`优化表`](optimize-table.html)table 捕获并抛出在将表统计信息从旧文件复制到新创建的文件时发生的任何错误。例如。如果所有者的用户 ID`.MYD`要么`。我的我`文件与用户 ID 不同[**mysqld**](mysqld.html)过程，[`优化表`](optimize-table.html)生成“无法更改文件的所有权”错误，除非[**mysqld**](mysqld.html)由`根`用户。

##### InnoDB 详细信息

为了`InnoDB`表，[`优化表`](optimize-table.html)映射到[`改变表...力`](alter-table.html)，它会重建表以更新索引统计信息并释放聚集索引中未使用的空间。这显示在输出中[`优化表`](optimize-table.html)当你在一个`InnoDB`表，如下所示：

```
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.html)用途[在线 DDL](innodb-online-ddl.html)对于常规和分区`InnoDB`表，这减少了并发 DML 操作的停机时间。由触发的表重建[`优化表`](optimize-table.html)就地完成。排他表锁仅在操作的准备阶段和提交阶段被短暂使用。在准备阶段，更新元数据并创建中间表。在提交阶段，将提交表元数据更改。

[`优化表`](optimize-table.html)在以下情况下使用表复制方法重建表：

-   当。。。的时候[`old_alter_table`](server-system-variables.html#sysvar_old_alter_table)系统变量已启用。

-   当服务器启动时[`--skip-new`](server-options.html#option_mysqld_skip-new)选项。

[`优化表`](optimize-table.html)使用[在线 DDL](innodb-online-ddl.html)不支持`InnoDB`包含的表`全文`索引。而是使用表复制方法。

`InnoDB`使用页面分配方法存储数据，并且不会像传统存储引擎（例如`MyISAM`） 做。在考虑是否运行优化时，请考虑您的服务器预期处理的事务的工作负载：

-   预计会有一定程度的碎片化。`InnoDB`只填[页面](glossary.html#glos_page)93% 已满，无需拆分页面即可为更新留出空间。

-   删除操作可能会留下空白，使页面的填充量低于预期，这使得优化表是值得的。

-   当有足够的空间可用时，根据数据类型和行格式，对行的更新通常会重写同一页中的数据。看[第 15.9.1.5 节，“InnoDB 表的压缩如何工作”](innodb-compression-internals.html)和[第 15.10 节，“InnoDB 行格式”](innodb-row-format.html).

-   随着时间的推移，高并发工作负载可能会在索引中留下空白，因为`InnoDB`由于通过其保留相同数据的多个版本[MVCC](glossary.html#glos_mvcc)机制。看[第 15.3 节，“InnoDB 多版本”](innodb-multi-versioning.html).

##### MyISAM 详细信息

为了`MyISAM`表，[`优化表`](optimize-table.html)工作方式如下：

1.  如果表已删除或拆分行，请修复表。

2.  如果索引页未排序，请对其进行排序。

3.  如果表的统计信息不是最新的（并且无法通过对索引进行排序来完成修复），请更新它们。

##### 其他注意事项

[`优化表`](optimize-table.html)在线执行常规和分区`InnoDB`表。否则，MySQL[锁定表](glossary.html#glos_table_lock)在那段时间里[`优化表`](optimize-table.html)在跑。

[`优化表`](optimize-table.html)不对 R-tree 索引进行排序，例如空间索引`观点`列。（错误 #23578）
