首先看一下語法:
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