OPTIMIZE [NO_WRITE_TO_BINLOG | LOCAL]
TABLE tbl_name [, tbl_name] ...
OPTIMIZE TABLE
會重新組織資料表資料和相關索引資料的實體儲存,以減少儲存空間,並在存取資料表時提高 I/O 效率。對每個資料表所做的確切變更取決於該資料表使用的儲存引擎。
在這些情況下使用 OPTIMIZE TABLE
,具體取決於資料表的類型
在對啟用
innodb_file_per_table
選項所建立的InnoDB
資料表進行大量的插入、更新或刪除操作後,由於該資料表擁有自己的 .ibd 檔案,因此可以重新組織資料表和索引,並回收磁碟空間供作業系統使用。在對
InnoDB
資料表中屬於FULLTEXT
索引一部分的欄位進行大量的插入、更新或刪除操作後,首先設定組態選項innodb_optimize_fulltext_only=1
。為了將索引維護時間保持在合理範圍內,請設定innodb_ft_num_word_optimize
選項,以指定要在搜尋索引中更新多少個單字,並執行一系列的OPTIMIZE TABLE
陳述式,直到搜尋索引完全更新為止。在刪除
MyISAM
或ARCHIVE
資料表的大部分資料,或對具有可變長度列的MyISAM
或ARCHIVE
資料表(具有VARCHAR
、VARBINARY
、BLOB
或TEXT
欄位的資料表)進行許多變更後,已刪除的列會維護在一個連結清單中,後續的INSERT
操作會重複使用舊的列位置。您可以使用OPTIMIZE TABLE
來回收未使用的空間並整理資料檔案。在對資料表進行大量變更後,此陳述式也可能會提高使用該資料表的陳述式效能,有時甚至會顯著提高。
此陳述式需要該資料表的 SELECT
和 INSERT
權限。
OPTIMIZE TABLE
適用於 InnoDB
、MyISAM
和 ARCHIVE
資料表。OPTIMIZE TABLE
也支援記憶體中 NDB
資料表的動態欄位。它不適用於記憶體中資料表的固定寬度欄位,也不適用於磁碟資料表。OPTIMIZE
在 NDB Cluster 資料表上的效能可以使用 --ndb-optimization-delay
來調整,該選項控制 OPTIMIZE TABLE
處理批次列之間等待的時間長度。如需詳細資訊,請參閱 第 25.2.7.11 節,「NDB Cluster 8.4 中解決的先前 NDB Cluster 問題」。
對於 NDB Cluster 資料表,OPTIMIZE TABLE
可以被中斷(例如)藉由終止執行 OPTIMIZE
操作的 SQL 執行緒。
預設情況下,OPTIMIZE TABLE
不 適用於使用任何其他儲存引擎建立的資料表,並會傳回一個指出此不支援的結果。您可以藉由使用 --skip-new
選項啟動 mysqld,使 OPTIMIZE TABLE
適用於其他儲存引擎。在這種情況下,OPTIMIZE TABLE
只是對應到 ALTER TABLE
。
此陳述式不適用於檢視。
OPTIMIZE TABLE
支援分割資料表。有關將此陳述式用於分割資料表和資料表分割區的資訊,請參閱 第 26.3.4 節,「分割區的維護」。
預設情況下,伺服器會將 OPTIMIZE TABLE
陳述式寫入二進位日誌,以便它們複製到複本。若要抑制記錄,請指定選用的 NO_WRITE_TO_BINLOG
關鍵字或其別名 LOCAL
。您必須具有 OPTIMIZE_LOCAL_TABLE
權限才能使用此選項。
OPTIMIZE TABLE
會傳回一個結果集,其中包含下表中顯示的欄位。
欄位 | 值 |
---|---|
資料表 |
資料表名稱 |
Op |
一律為 optimize |
Msg_type |
status 、error 、info 、note 或 warning |
Msg_text |
資訊訊息 |
OPTIMIZE TABLE
資料表會捕捉並擲回在將資料表統計資料從舊檔案複製到新建立的檔案時發生的任何錯誤。例如,如果 .MYD
或 .MYI
檔案擁有者的使用者 ID 與 mysqld 程序的使用者 ID 不同,除非 mysqld 是由 root
使用者啟動的,否則 OPTIMIZE TABLE
會產生「無法變更檔案所有權」錯誤。
對於 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
在下列情況下會使用資料表複製方法重建資料表
啟用
old_alter_table
系統變數時。當伺服器使用
--skip-new
選項啟動時。
包含 FULLTEXT
索引的 InnoDB
資料表不支援使用 線上 DDL 的 OPTIMIZE TABLE
。而是使用資料表複製方法。
InnoDB
使用頁面配置方法儲存資料,且不會像舊版儲存引擎(例如 MyISAM
)一樣遭受破碎。在考慮是否執行最佳化時,請考慮伺服器預期處理的交易工作負載
預期會有一定程度的破碎。
InnoDB
只會將 頁面填滿 93%,以便為更新保留空間,而無需分割頁面。刪除操作可能會留下間隙,導致頁面填滿度低於預期,這可能會讓最佳化資料表值得執行。
通常會在同一個頁面內重寫列的更新,具體取決於資料類型和列格式,前提是有足夠的空間可用。請參閱 第 17.9.1.5 節,「InnoDB 資料表的壓縮運作方式」和 第 17.10 節,「InnoDB 列格式」。
由於
InnoDB
會透過其 MVCC 機制保留相同資料的多個版本,因此高並行工作負載可能會隨著時間推移在索引中留下間隙。請參閱 第 17.3 節,「InnoDB 多版本處理」。
對於 MyISAM
資料表,OPTIMIZE TABLE
的運作方式如下
如果資料表有已刪除或分割的列,請修復資料表。
如果索引頁面未排序,請對它們進行排序。
如果資料表的統計資料不是最新的(且無法透過排序索引來完成修復),請更新它們。
針對常規和分割的 InnoDB
資料表,OPTIMIZE TABLE
會在線上執行。否則,MySQL 會在 OPTIMIZE TABLE
執行期間鎖定資料表。
OPTIMIZE TABLE
不會對 R 樹狀索引進行排序,例如 POINT
欄位上的空間索引。(錯誤 #23578)