首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

MySQL OPTIMIZE TABLE 深度解析:原理、適用場景與操作指南

     編輯:MySQL 資料庫相關知識

為什麼需要 OPTIMIZE TABLE?

大量 DELETE、UPDATE 可變長度列(VARCHAR/BLOB/TEXT)後,資料檔案會產生碎片,檔案大小不減反增,讀寫效能下降。Discuz! 等系統內建「資料表優化」功能即呼叫此命令。

語法

OPTIMIZE [LOCAL | NO_WRITE_TO_BINLOG] TABLE tbl_name [, tbl_name] ...;
  • LOCAL / NO_WRITE_TO_BINLOG:不寫入二進位日誌,不複寫到從庫。

運作原理

  1. 建立原表的臨時副本。
  2. 將資料重新整理寫入副本(重建索引、壓縮碎片)。
  3. 原子替換原表。

全程鎖表,大表操作時間較長,建議低峰期執行。

引擎別行為差異

適用場景

  • 刪除大量資料後。
  • 頻繁更新可變長度列(VARCHAR/BLOB/TEXT)的表。
  • 定期維護:每週/每月一次,僅針對碎片嚴重表。
  • 不需 對唯讀、固定長度、少量變動的表頻繁執行。

碎片檢測:判斷是否需要優化

SELECT
    TABLE_NAME,
    DATA_LENGTH,
    INDEX_LENGTH,
    DATA_FREE,
    ROUND(DATA_FREE / (DATA_LENGTH + INDEX_LENGTH) * 100, 2) AS frag_pct
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = 'your_db'
  AND DATA_FREE > 0
ORDER BY frag_pct DESC;

frag_pct > 20% 建議排程優化。

線上優化替代方案(減少鎖表影響)

  • pt-online-schema-change (Percona Toolkit):觸發器+臨時表,近零停機重建。
  • gh-ost (GitHub):無觸發器,基於 binlog 同步,更安全。
  • MySQL 8.0+ ALTER TABLE ... ALGORITHM=INPLACE, LOCK=NONE 部分操作支援線上。

複寫注意事項

預設寫入 binlog 並複寫到從庫。大表優化會導致從庫同步延遲。跨機房複寫建議加 NO_WRITE_TO_BINLOG,改由人工在從庫各自執行。

總結檢查清單

  1. 確認表引擎支援(MyISAM/InnoDB)。
  2. 檢測碎片率 > 20%。
  3. 選擇低峰期,預估鎖表時間(大表可用線上工具)。
  4. 決定是否複寫(NO_WRITE_TO_BINLOG)。
  5. 執行 OPTIMIZE TABLE 或線上替代方案。
  6. 驗證 DATA_FREE 歸零、檔案縮小、查詢效能提升。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
引擎實際動作
MyISAM修復表 → 排序索引頁 → 更新統計資訊
InnoDB映射為 ALTER TABLE ... ENGINE=InnoDB 重建表,更新索引統計、釋放叢集索引空間
BDB (已棄用)映射為 ANALYZE TABLE