OPTIMIZE [NO_WRITE_TO_BINLOG | LOCAL]
TABLE tbl_name [, tbl_name] ...
OPTIMIZE TABLE
會重新組織表格資料和相關索引資料的實體儲存,以減少儲存空間,並在存取表格時提高 I/O 效率。對每個表格所做的確切變更取決於該表格所使用的儲存引擎。
在以下情況下使用 OPTIMIZE TABLE
,具體取決於表格類型:
在對
InnoDB
表格執行大量的插入、更新或刪除操作後,如果該表格擁有自己的 .ibd 檔案,因為它是在啟用innodb_file_per_table
選項的情況下建立的。表格和索引會被重新組織,並且可以回收磁碟空間供作業系統使用。在對
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
來回收未使用的空間並整理資料檔。在對表格進行大量變更後,此陳述式也可能會提高使用該表格的陳述式的效能,有時會顯著提高。
OPTIMIZE TABLE
適用於 InnoDB
、MyISAM
和 ARCHIVE
表格。OPTIMIZE TABLE
也支援記憶體中 NDB
表格的動態欄位。它不適用於記憶體中表格的固定寬度欄位,也不適用於磁碟資料表格。OPTIMIZE
在 NDB Cluster 表格上的效能可以使用 --ndb-optimization-delay
進行調整,該選項控制 OPTIMIZE TABLE
處理成批列之間要等待的時間長度。如需更多資訊,請參閱第 25.2.7.11 節:「先前在 NDB Cluster 9.0 中已解決的 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
將線上 DDL 用於規則和分割的 InnoDB
表格,這減少了並行 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)