先來說一下什麼是碎片,怎麼知道碎片有多大!
簡單的說,刪除資料必然會在資料檔案中造成不連續的空白空間,而當插入資料時,這些空白空間則會被利用起來.於是造成了資料的儲存位置不連續,以及物理儲存順序與理論上的排序順序不同,這種是資料碎片.實際上資料碎片分為兩種,一種是單行資料碎片,另一種是多行資料碎片.前者的意思就是一行資料,被分成N個片段,儲存在N個位置.後者的就是多行資料並未按照邏輯上的順序排列.當有大量的刪除和插入操作時,必然會產生很多未使用的空白空間,這些空間就是多出來的額外空間.索引也是檔案資料,所以也會產生索引碎片,理由同上,大概就是順序紊亂的問題.Engine 不同,OPTIMIZE 的操作也不一樣的,MyISAM 因為索引和資料是分開的,所以 OPTIMIZE 可以整理資料檔案,並重排索引。這樣不但會浪費空間,並且查詢速度也更慢。
解決方案:(切記,一定要在夜裡執行,表越大,越耗資源時間,不要頻繁修復,可以幾個月甚至一年修復一次,如果表頻繁被更改,可以按周/月來整理。)
檢視錶碎片的方法
mysql> select ROW_FORMAT,TABLE_ROWS,DATA_LENGTH,INDEX_LENGTH,MAX_DATA_LENGTH,DATA_FREE,ENGINE from TABLES where TABLE_SCHEMA='test_db' and TABLE_NAME='table_name' limit 1;
通過OPTIMIZE TABLE table_name 後再查詢一下結果如下
也可以觀察Mysql的資料目錄儲存檔案Data檔案大小,如MYD
一、Innodb儲存引擎清理碎片方法
ALTER TABLE tablename ENGINE=InnoDB
二、Myisam儲存引擎清理碎片方法
OPTIMIZE 操作會暫時鎖住表,而且資料量越大,耗費的時間也越長,它畢竟不是簡單查詢操作.所以把 Optimize 命令放在程式中是不妥當的,不管設定的命中率多低,當訪問量增大的時候,整體命中率也會上升,這樣肯定會對程式的執行效率造成很大影響.比較好的方式就是做個 Script,定期檢查mysql中 information_schema.TABLES欄位,檢視 DATA_FREE 欄位,大於0話,就表示有碎片.指令碼多長時間執行一次,可以根據實際情況來定,比如每週跑一次.
OPTIMIZE TABLE table_name