OPTIMIZE [NO_WRITE_TO_BINLOG | LOCAL]
TABLE tbl_name [, tbl_name] ...
OPTIMIZE TABLE
重组表数据和关联索引数据的物理存储,减少存储空间,提高访问表时的I/O效率。对每个表所做的确切更改取决于该
表使用的存储引擎。
在这些情况下使用OPTIMIZE TABLE
,具体取决于表的类型:
InnoDB
在对具有自己的 .ibd 文件 的表执行大量插入、更新或删除操作之后,因为它是在innodb_file_per_table
启用选项的情况下创建的。重组了表和索引,可以回收磁盘空间供操作系统使用。FULLTEXT
在对作为表中索引 一部分的列执行大量插入、更新或删除操作之后InnoDB
。首先设置配置选项innodb_optimize_fulltext_only=1
。要将索引维护周期保持在合理的时间,请设置innodb_ft_num_word_optimize
选项以指定要在搜索索引中更新多少个单词,并运行一系列OPTIMIZE TABLE
语句,直到搜索索引完全更新。MyISAM
在删除or表 的大部分,或对具有可变长度行(具有 、 、 或 列的表)的or表ARCHIVE
进行多次更改后。删除的行在链表中维护,后续 操作重用旧行位置。您可以使用它来回收未使用的空间并对数据文件进行碎片整理。在对表进行大量更改后,此语句还可以提高使用该表的语句的性能,有时效果会很显着。MyISAM
ARCHIVE
VARCHAR
VARBINARY
BLOB
TEXT
INSERT
OPTIMIZE TABLE
OPTIMIZE TABLE
适用于
InnoDB
、
MyISAM
和
ARCHIVE
表格。
OPTIMIZE TABLE
也支持内存
NDB
表的动态列。它不适用于内存表的固定宽度列,也不适用于磁盘数据表。OPTIMIZE
可以使用 调整 NDB Cluster 表
的性能--ndb-optimization-delay
,它控制处理批处理行之间等待的时间长度OPTIMIZE TABLE
。有关更多信息,请参阅
第 18.2.7.11 节,“NDB Cluster 7.3 中已解决的先前 NDB Cluster 问题”。
对于 NDB Cluster 表,OPTIMIZE
TABLE
可以通过(例如)杀死执行OPTIMIZE
操作的 SQL 线程来中断。
默认情况下,OPTIMIZE TABLE
不适
用于使用任何其他存储引擎创建的表,并返回表明缺乏支持的结果。您可以通过使用该
选项启动mysqldOPTIMIZE
TABLE
来为其他存储引擎工作
。在这种情况下,
只是映射到
.
--skip-new
OPTIMIZE TABLE
ALTER TABLE
此语句不适用于视图。
OPTIMIZE TABLE
分区表支持。有关将此语句用于分区表和表分区的信息,请参阅
第 19.3.4 节,“分区维护”。
默认情况下,服务器将OPTIMIZE
TABLE
语句写入二进制日志,以便它们复制到副本。要禁止记录日志,请指定可选
NO_WRITE_TO_BINLOG
关键字或其别名
LOCAL
。
仅在 MySQL 5.6.11 中,gtid_next
必须AUTOMATIC
在发出此语句之前设置为。(错误#16062608、错误#16715809、错误#69045)
OPTIMIZE TABLE
返回一个结果集,其列如下表所示。
柱子 | 价值 |
---|---|
Table |
表名 |
Op |
总是optimize |
Msg_type |
status , error ,
info ,note 或
warning |
Msg_text |
信息性消息 |
OPTIMIZE TABLE
table 捕获并抛出将表统计信息从旧文件复制到新创建的文件时发生的任何错误。例如。如果 、 或文件所有者的
.frm
用户.MYD
ID
.MYI
与mysqld进程的用户 ID 不同,
OPTIMIZE TABLE
则会生成“无法更改文件的所有权”错误,除非
mysqld由
root
用户启动。
对于InnoDB
表,
OPTIMIZE TABLE
映射到
ALTER TABLE ...
FORCE
,它重建表以更新索引统计信息并释放聚簇索引中未使用的空间。OPTIMIZE
TABLE
当您在表上运行它时,它
会显示在输出中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 |
+----------+----------+----------+-------------------------------------------------------------------+
Mysql 5.6.17之前,OPTIMIZE
TABLE
不使用
在线DDL。因此,并发 DML ( INSERT
,
UPDATE
,
DELETE
) 在运行时不允许在表OPTIMIZE TABLE
上使用,并且二级索引的创建效率不高。
从 MySQL 5.6.17 开始,对常规表和分区
表OPTIMIZE
TABLE
使用在线 DDLInnoDB
,这减少了并发 DML 操作的停机时间。触发的表重建
OPTIMIZE TABLE
就地完成。独占表锁仅在操作的准备阶段和提交阶段短暂使用。在准备阶段,更新元数据并创建中间表。在提交阶段,提交表元数据更改。
OPTIMIZE TABLE
在以下条件下使用表复制方法重建表:
old_alter_table
启用系统变量 时。当服务器启动时带有
--skip-new
选项。
OPTIMIZE TABLE
包含
索引的表不支持使用
联机 DDL 。改为使用表复制方法。
InnoDB
FULLTEXT
InnoDB
使用页面分配方法存储数据,并且不会像传统存储引擎(例如
MyISAM
)那样受到碎片的影响。在考虑是否运行优化时,请考虑您的服务器预期处理的事务工作量:
预计会出现某种程度的碎片化。
InnoDB
只填满 93% 的页面,无需拆分页面即可为更新留出空间。删除操作可能会留下间隙,使页面填充少于预期,这可能值得优化表。
当有足够的空间可用时,对行的更新通常会重写同一页中的数据,具体取决于数据类型和行格式。请参阅 第 14.9.5 节,“InnoDB 表的压缩工作原理”和 第 14.11 节,“InnoDB 行格式”。
随着时间的推移,高并发工作负载可能会在索引中留下空白,因为通过其MVCC机制
InnoDB
保留了相同数据的多个版本 。请参阅 第 14.3 节,“InnoDB 多版本控制”。
对于MyISAM
表格,
OPTIMIZE TABLE
其工作方式如下:
如果表有删除或拆分行,修复表。
如果索引页未排序,请对它们进行排序。
如果表的统计信息不是最新的(并且无法通过对索引进行排序来完成修复),请更新它们。
对于InnoDB
5.6.17 之前的表和其他表类型,MySQL在运行期间锁定表OPTIMIZE
TABLE
。从 MySQL 5.6.17 开始,
OPTIMIZE TABLE
对常规表和分区InnoDB
表在线执行。
OPTIMIZE TABLE
不对 R 树索引进行排序,例如
POINT
列上的空间索引。(漏洞 #23578)