數(shù)據(jù)庫優(yōu)化之常用的show table status及ALTER TABLE 重建表

當面試官讓你聊聊MySQL數(shù)據(jù)庫性能優(yōu)化,你還是只能回答優(yōu)化sql,建索引嗎?
讓我們看看還可以從哪些方面聊聊吧。其實你還可以從網(wǎng)速、數(shù)據(jù)量、數(shù)據(jù)庫日志、內存等問題、硬件配置,當前占用資源、硬盤碎片或索引碎片等等諸多方面分析聊聊。

一、show table status from db_name【 如何判斷是否有碎片?】

1、碎片查詢分析

show status可以查看MySQL服務器運行狀態(tài)值。而show table status from db_name可以查詢db_name 數(shù)據(jù)庫里所有表的信息,是否有索引碎片等。MySQL 的表空間設置和優(yōu)化策略有什么?

這個命令中 Data_free 字段,如果該字段不為 0,則產生了數(shù)據(jù)碎片。

show table status 查詢結果中各列字段含義

  • Name 表名稱
  • Engine 表的存儲引擎,對于分區(qū)表,Engine 顯示所有分區(qū)使用的存儲引擎的名稱。
  • Version 版本;此列未使用。在 MySQL 8.0 中刪除 .frm 文件后,此列現(xiàn)在報告硬編碼值 10,這是 MySQL 5.7 中使用的最后一個 .frm 文件版本。
  • Row_format 行格式。對于MyISAM引擎,這可能是Dynamic,F(xiàn)ixed或Compressed。動態(tài)行的行長度可變,例如Varchar或Blob類型字段。固定行是指行長度不變,例如Char和Integer類型字段。
  • Rows 行數(shù)。一些存儲引擎,例如 MyISAM,存儲確切的計數(shù)。對于其他存儲引擎,例如 InnoDB,這個值是一個近似值,可能與實際值相差 40% 到 50%。在這種情況下,請使用 SELECT COUNT(*) 獲得準確的計數(shù)。
    對于 INFORMATION_SCHEMA 表,Rows 值為 NULL。
    對于 InnoDB 表,行數(shù)只是 SQL 優(yōu)化中使用的粗略估計。 (如果 InnoDB 表是分區(qū)的,這也是如此。)
  • Avg_row_length 平均每行包括的字節(jié)數(shù)
  • Data_length 對于 MyISAM,Data_length 是數(shù)據(jù)文件的長度,以字節(jié)為單位。
    對于 InnoDB,Data_length 是為聚集索引分配的近似空間量,以字節(jié)為單位。具體來說,它是聚集索引大?。ㄒ皂撁鏋閱挝唬┏艘?InnoDB 頁面大小。
    對于 MyISAM,Max_data_length 是數(shù)據(jù)文件的最大長度。給定使用的數(shù)據(jù)指針大小,這是可以存儲在表中的數(shù)據(jù)總字節(jié)數(shù)。
  • Max_data_length 對于 MyISAM,Max_data_length 是數(shù)據(jù)文件的最大長度。給定使用的數(shù)據(jù)指針大小,這是可以存儲在表中的數(shù)據(jù)總字節(jié)數(shù)。
    未用于 InnoDB。
  • Index_length 對于 MyISAM,Index_length 是索引文件的長度,以字節(jié)為單位。
    對于 InnoDB,Index_length 是為非聚集索引分配的近似空間量,以字節(jié)為單位。具體來說,它是非聚集索引大小的總和,以頁面為單位,乘以 InnoDB 頁面大小。
  • Data_free 已分配但未使用的字節(jié)數(shù)。
    InnoDB 表報告該表所屬表空間的可用空間。對于位于共享表空間中的表,這是共享表空間的空閑空間。如果您使用多個表空間并且該表有自己的表空間,則可用空間僅用于該表??臻e空間是指完全空閑范圍中的字節(jié)數(shù)減去安全裕度。即使可用空間顯示為 0,只要不需要分配新的擴展區(qū),就可以插入行。

2、產生碎片的原因

  • 經(jīng)常進行 delete 操作
    經(jīng)常進行 delete 操作,產生空白空間,久而久之就產生了碎片;

  • update 更新
    update 更新可變長度的字段(例如 varchar 類型),將長的字符串更新成短的。之前存儲的內容長,后來存儲是短的,即使后來插入新數(shù)據(jù),那么有一些空白區(qū)域還是沒能有效利用的。

由于碎片空間是不連續(xù)的,導致這些空間不能充分被利用;由于碎片的存在,導致數(shù)據(jù)庫的磁盤 I/O 操作變成離散隨機讀寫,加重了磁盤 I/O 的負擔。

二、MySQL 的表空間設置和優(yōu)化策略【 如何清理碎片?】

如何清理碎片,加快索引掃描,給表空間瘦身呢,常用的方法可以從以下幾個方面進行處理:

1、innodb_file_per_table 參數(shù)設置為 ON(基本上是默認打開的)

  • 打開該參數(shù),創(chuàng)建表則會分2個文件,.frm存放元數(shù)據(jù),.ibd存放表數(shù)據(jù)(表初始大小是98304KB);
  • 關掉該參數(shù)off之后,創(chuàng)建表,只會生成.frm元數(shù)據(jù)文件,數(shù)據(jù)會存放到系統(tǒng)表空間,這樣會不利于后期管理,系統(tǒng)表空間會逐漸膨脹,導致影響性能。

2、定期執(zhí)行 OPTIMIZE TABLE tableName;

MyISAM

optimize table 表名;(OPTIMIZE 可以整理數(shù)據(jù)文件,并重排索引)

對于MYISAM表,OPTIMIZE TABLE 的工作原理:
如果表已刪除或分隔行,就修復該表。
如果索引頁沒有排序,就排序它們。
如果表的統(tǒng)計信息不是最新的(而且修復不能通過對索引進行排序),就更新它們。

Innodb

optimize table 表名;
對于InnoDB的表,OPTIMIZE TABLE 的工作原理如下
對于InnoDB表, OPTIMIZE TABLE映射到ALTER TABLE … FORCE(或者這樣翻譯:在InnoDB表中等價 ALTER TABLE … FORCE),它重建表以更新索引統(tǒng)計信息并釋放聚簇索引中未使用的空間。

3、定期執(zhí)行 ALTER TABLE tableName ENGINE = InnoDB;

Innodb
方法一:ALTER TABLE tablename ENGINE=InnoDB;(重建表存儲引擎,重新組織數(shù)據(jù))
或:ALTER TABLE tbl_name FORCE;

方法二:進行一次數(shù)據(jù)的導入導出
使用 mysqldump 將表轉儲到文本文件,刪除表,然后從轉儲文件重新加載

注意:第optimize、ALTER TABLE是高危操作,會鎖表,影響業(yè)務,建議在低峰期操作。

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容