MySQL清除表空間碎片(對于Innodb 引擎的 共享空間:Innodb 共享空間自己試過就是清理不掉,是以對于Innodb 共享空間我的解決方法是把Innodb 修改成獨立表空間)
摘要:清除碎片操作會暫時鎖表,資料量越大,耗費的時間越長,可以做個腳本,定期在通路低谷時間執行,例如每周三淩晨,檢查DATA_FREE字段,大于自己認為的警戒值的話,就清理一次。
碎片産生的原因(1)表的存儲會出現碎片化,每當删除了一行内容該段空間就會變為空白、被留白,而在一段時間内的大量删除操作,會使這種留白的空間變得比存儲清單内容所使用的空間更大;
(2)當執行插入操作時,MySQL會嘗試使用空白空間,但如果某個空白空間一直沒有被大小合适的資料占用,仍然無法将其徹底占用,就形成了碎片;
(3)當MySQL對資料進行掃描時,它掃描的對象實際是清單的容量需求上限,也就是資料被寫入的區域中處于峰值位置的部分;
例如:
一個表有1萬行,每行10位元組,會占用10萬位元組存儲空間,執行删除操作,隻留一行,實際内容隻剩下10位元組,但MySQL在讀取時,仍看做是10萬位元組的表進行處理,是以,碎片越多,就會越來越影響查詢性能。
檢視表碎片大小
(1)檢視某個表的碎片大小
mysql> SHOW TABLE STATUS LIKE ‘表名’;
結果中’Data_free’列的值就是碎片大小
(2)列出所有已經産生碎片的表
mysql> select table_schema db, table_name, data_free, engine from information_schema.tables where table_schema not in (‘information_schema’, ‘mysql’) and data_free > 0;
清除表碎片
(1)MyISAM表
mysql> optimize table 表名
(2)InnoDB表
mysql> alter table 表名 engine=InnoDB
Engine不同,OPTIMIZE 的操作也不一樣的,MyISAM 因為索引和資料是分開的,是以 OPTIMIZE 可以整理資料檔案,并重排索引.
OPTIMIZE 操作會暫時鎖住表,而且資料量越大,耗費的時間也越長,它畢竟不是簡單查詢操作.是以把 Optimize 指令放在程式中是不妥當的,不管設定的命中率多低,當通路量增大的時候,整體命中率也會上升,這樣肯定會對程式的運作效率造成很大影響.比較好的方式就是做個shell,定期檢查mysql中 information_schema.TABLES字段,檢視 DATA_FREE 字段,大于0話,就表示有碎片
建議:清除碎片操作會暫時鎖表,資料量越大,耗費的時間越長,可以做個腳本,定期在通路低谷時間執行,例如每周三淩晨,檢查DATA_FREE字段,大于自己認為的警戒值的話,就清理一次。
轉載: http://blog.csdn.net/eagle89/article/details/78017505
//shell腳本如下:
mysql_user=root
mysql_pass=xxxx
time_log=/opt/database/time
databases=/opt/database/databases
mysql -u mysqluser−p m y s q l u s e r − p mysql_pass -e “show databases” | grep -v “Database” > databasessed−i“s/informationschema//” d a t a b a s e s s e d − i “ s / i n f o r m a t i o n s c h e m a / / ” (cat /opt/database/databases)
for i in databases1doecho“database d a t a b a s e s 1 d o e c h o “ d a t a b a s e i staring”
tables= (mysql ( m y s q l i -u mysqluser−p m y s q l u s e r − p mysql_pass -e “show tables” | grep -v “Tables” > /opt/database/ i)tablelist= i ) t a b l e l i s t = (cat /opt/database/ i)echo“optimizedatabase i ) e c h o “ o p t i m i z e d a t a b a s e i starting" >> timelogecho“ t i m e l o g e c h o “ i start at (date+[ ( d a t e + [ time_log
for list in tablelistdoecho t a b l e l i s t d o e c h o list
mysql i−u i − u mysql_user -p mysqlpass−e"altertable m y s q l p a s s − e " a l t e r t a b l e list engine=InnoDB”
done
echo “ iendas i e n d a s (date +[%Y/%m/%d/%H/%M/%S])” >> timelogecho>> t i m e l o g e c h o >> time_log
done