首先看一下语法:
OPTIMIZE [NO_WRITE_TO_BINLOG | LOCAL] TABLE tbl_name [, tbl_name] ...
咱们知道mysql存储引擎里面的数据和索引数据都是物理存储的,因此说为了减小空间使用和访问表的时候能有更好的IO表现,因此说当表执行OPTIMIZE TABLE的时候,是会发生切实的变化的.
通常如下集中状况下,咱们会使用OPTIMIZE TABLE来进行优化:
1:在大量的插入,更新,或者删除INNODB表之后,咱们再执行是颇有必要的.此时若是执行OPTIMIZE TABLE的话,整表和表上全部的索引都会重组,并且不使用的表空间会被回收给操做系统.
2:在大量的插入,更新,或者删除有全文索引的INNODB表的字段之后,不过要首先设置innodb_optimize_fulltext_only=1,也能够经过指定innodb_ft_num_word_optimize 的值来指定能在索引里面更新多少记录.记录数满的时候就要经过OPTIMIZE TABLE来优化表.
3:在 MyISAM和 ARCHIVE 表作大量的删除的时候就须要执行OPTIMIZE TABLE,或者是 MyISAM和 ARCHIVE 表作了字段长度的更改,若是此时表中有大字段的话,就更须要执行OPTIMIZE TABLE 来优化表了.由于被删除的记录的位置仍是会保存,并不会进行回收,等待新纪录插入,或者OPTIMIZE TABLE 进行重组才回回收.并且最重要的一点是OPTIMIZE TABLE之后性能会获得很大的提高,特别是表作过较大的变动之后在执行,性能提高会很是的明显.
OPTIMEZE TABLE 须要的权限:
对表insert 和 select权限.
并且OPTIMIZE TABLE 对分区表也是支持的,具体的语法是
ALTER TABLE t1 OPTIMIZE PARTITION p0, p1;
从上面就能够看出来OPTIMEZE TABLE对于INNODB,MyISAM和 ARCHIVE 的表都是适用的,对于其余引擎的数据表都是不适用的,若是想要使用OPTIMIZE TABLE 优化表,就要在启动mysqld的时候使用--skip-new参数启动.
OPTIMIZE TABLE 能够在线DDL,经过指定(ALGORITHM=INPLACE) ,不过这个只支持INNODB表,普通表和分区表都是支持的.表重建的方式有两种,OPTIMIZE TABLE 和 ALTER TABLE ... FORCE两种方式均可以触发表重建.
OPTIMIZE TABLE 也有适用于 ALGORITHM=COPY的一些条件:
1:当old_alter_table参数设置为ON的时候,OPTIMIZE并不会重建,而是使用一个临时表先把记录插进去来作处理.这个时候就要使用ALGORITHM=COPY来处理了.
2:当mysqld以--skip-new 为方式启动的时候
3:当INNODB表含有全文索引的时候 ,就只可以使用ALGORITHM=COPY来进行优化了
INNODB的数据存储是按照page-allocation的方式存储的,这和MYASIM引擎是不相同的,因此当咱们考虑要OPTIMEZE一张表的时候,必定要先考虑如下的几个问题:
1:INNODB表的索引碎片是有所保留的,通常状况下是最多只可以占用93%的,剩余的一些是要保留起来用于update更新时候的页分裂来分配空间
2:删除操做会留下一部分的空间,只有当OPTIMIZE TABLE的时候才会从新的回收.
3:update的记录等因而对原有的数据页进行从新的写入,这和数据类型和行格式是有很大关系的.这个是有前提条件的,就是原有的页有足够的空间可以书写新数据.
4:高并发的状况下,会形成索引的间隙,这个产生的主要缘由就是由于MySQL的事物是基于MVCC来实现的.
OPTIMIZE TABLE 对于MYASIM表的支持:
1:若是表有删除或者行拆分的话,就要repair table
2:若是索引页没有划分,就会从新划分索引页
3:统计信息若是不许确的话,就会从新更新统计信息
OPTIMIZE TABLE 返回信息尅看一下:
Column |
Value |
Table |
The table name |
Op |
Always optimize |
Msg_type |
status, error, info, note, or warning |
Msg_text |
An informational message |
可是还要记住一点就是5.7.4之前的版本OPTIMIZE TABLE的时候会锁定全表,以后版本的INNODB表就就能够在线OPTIMIZE 了.并且更重要的是OPTIMIZE TABLE 会记录二进制日志,因此说对于复制的机器是会传送到slave上的.并且他对R-TREE结构的索引是不起做用的.
快速分析mysql的表信息,MYASIM引擎:
myisamchk --quick --check-only-changed --sort-index --analyze
从新组织表:
ALTER TABLE [tbl_name] TYPE=innodb
修改表行格式:
alter table your_table row_format=compressed