MySQL中的分析表、检查表与优化表如何操作?
MySQL提供了分析表、檢查表和優化表的語句。分析表主要是分析關鍵字的分布,檢查表主要是檢查表是否存在錯誤,優化表主要是消除刪除或者更新造成的空間浪費。
【1】分析表
MySQL中提供了 ANALYZE TABLE 語句分析表,analyze table 語句的基本語法如下:
analyze [local | no_write_to_binlog] table table_name[,tbl_name]....默認的,MySQL服務會將analyze table語句寫到binlog中,以便在主從架構中,從服務能夠同步數據。可以添加參數 local 或者 no_write_to_binlog 取消將語句寫到binlog中。
使用 analyze table 分析表的過程中,數據庫系統會自動對表加一個 只讀鎖。 在分析期間,只能讀取表中的記錄,不能更新和插入記錄。analyze table 語句能夠分析 InnoDB和MyISAM類型的表,但是不能作用于視圖。
analyze table分析后的統計結果會反映到 cardinality 的值,該值統計了表中某一鍵所在的列不重復的值的個數。 該值越接近表中的總行數,則在表連接查詢或者索引查詢時,就越優先被優化器選擇使用。也就是索引列的 cardinality 的值與表中數據的總條數差距越大,即使查詢的時候使用了該索引作為查詢條件,存儲引擎實際查詢的時候使用的概率就越小。
下面通過例子來驗證一下,cardinality 可以通過 show index from table_name 查看。
CREATE TABLE `user1` (`id` int NOT NULL AUTO_INCREMENT,`name` varchar(255) DEFAULT NULL,`age` int DEFAULT NULL,`sex` varchar(255) DEFAULT NULL,PRIMARY KEY (`id`),KEY `idx_name` (`name`) USING BTREE ) ENGINE=InnoDB AUTO_INCREMENT=1001 DEFAULT CHARSET=utf8mb3;創建表user1,并插入1000條數據,其中name值均為jane 。此時我們執行 SHOW INDEX FROM user1;
如上圖所示,Cardinality 列 對于id 是12(其實應該是1000),對于name是1(實際就是1)。我們使用分析表語句 后再次查看:
上面結果顯示的信息說明如下:
- Table:表示分析的表的名稱
- Op:表示執行的操作。analyze表示進行分析操作
- Msg_type:表示信息類型,其值通常是狀態(status)、信息(info)、注意(note)、警告(warning)和錯誤(error)之一。
- Msg_text:顯示信息。
此時再次查看user表的 Cardinality,如下所示:
SHOW INDEX FROM user1;
可以看到id主鍵的Cardinality已經修正,和數據總量一致,此時索引已經修復,查詢效率大大提高。這個值只要大致相同就表示索引被優化器使用的概率就越大。
我們修改id=2的name值,然后再次分析查看,可以看到Cardinality列已經從 1 變成了 2:
# 修改值 update user1 set name='janus' where id=2; # 查看索引 SHOW INDEX FROM user1; # 分析表 analyze table user1; # 查看索引 SHOW INDEX FROM user1;
我們查看下面SQL的執行計劃:
explain select * from user1 where name='jane'結果如下所示,可以看到雖然name字段上面有索引,但是執行計劃中顯示type為’ALL’,表示并沒有使用到索引。
我們再看下面SQL的執行計劃:
結果如下所示,可以看到確實是用到了索引,檢索的行數rows為1。
這兩個SQL也說明了:
- 如果取值離散度太小,那么不太適合創建索引
- 如果創建了索引,那么查詢“索引取值少量數據”時才會用到索引
【2】檢查表
MySQL中可以使用 CHECK TABLE語句來檢查表。CHECK TABLE語句能夠檢查InnoDB和MyISAM類型的表是否存在錯誤。 CHECK TABLE語句在執行過程中也會給表加上只讀鎖。
對于MyISAM類型的表,CHECK TABLE 語句還會更新關鍵字統計數據。而且 CHECK TABLE也可以檢查視圖是否有錯誤,比如在視圖定義中被引用的表已不存在。
該語句的基本語法如下:
CHECK TABLE table_name[, table_name] ....[option]... option={QUICK | FAST | MEDIUM | EXTENDED |CHANGED }option各個選項的意義分別是:
- QUICK:不掃描行,不檢查錯誤的連接
- FAST:只檢查沒有被正確關閉的表
- CHANGED:只檢查上次檢查后被更改的表和沒有被正確關閉的表
- MEDIUM:掃描行,以驗證被刪除的連接是有效的。也可以計算各行的關鍵字校驗和,并使用計算出的校驗和驗證這一點。
- EXTENDED:對每行的所有關鍵字進行一個全面的關鍵字查找。這可以確保表時100%一致的,但是花的時間較長。
option只對MyISAM類型的表有效,對InnoDB類型的表無效。比如:
check table user1
該語句對于檢查的表可能會產生多行信息。最后一行有一個狀態的Msg_type值 ,Msg_text通常為OK。如果得到的不是OK,通常要對其進行修復;是OK說明表已經是最新的了。表已經是最新的,意味著存儲引擎對這張表不必進行檢查。
【3】優化表
① OPTIMIZE TABLE
MySQL中使用optimize table語句來優化表。但是,optimize table語句只能優化表中的varchar、blob或text類型的字段。一個表使用了這些字段的數據類型,若已經刪除了表的一大部分數據,或者已經對含有可變長度行的表(含有varchar、blob或text列的表)進行了很多更新,則應使用optimize table來重新利用未使用的空間,并整理數據文件的碎片。
optimize table語句對InnoDB和MyISAM類型的表都有效。該語句在執行過程中也會給表加上只讀鎖。optimize table語句的基本語法如下:
optimize [local | no_write_to_binlog] table table_name [,table_name]...local | no_write_to_binlog 關鍵字的意義和分析表相同,都是指定不寫入二進制日志。
如下所示,我們在user1中插入十萬條數據,占用空間如下:
如下所示,我們刪除一半數據,再次查看該文件,發現占用大小并未改變
delete from user1 where id>50000優化表之后再次查看,發現文件占用空間變小:
optimize table user1;
上圖(優化結果示意圖)是正常的,針對MySQL的InnoDB引擎,optimize結果就是那樣的(官網有說明)。在MyISAM中,是先分析這張表,然后會整理相關的MySQL datafile,之后回收未使用的空間。在InnoDB中,回收空間是簡單通過alter table 進行整理空間。在優化期間,MySQL會創建一個臨時表,優化完成之后會刪除原始表,然后會將臨時表rename成為原始表。
注意,在多數的設置中,根本不需要運行 optimize table。即使對可變長度的行進行了大量的更新,也不需要經常運行,每周一次或每月一次即可。并且只需要對特定的表運行。
② mysqlcheck
mysqlcheck -o DatabaseName tableName -uroot -p******mysqlcheck是Linux中的rompt,-o是代表Optimize。
舉例:優化所有表:
mysqlcheck -o DatabaseName -u root -p**** # 或 mysqlcheck -o --all-databases -u root -p****總結
以上是生活随笔為你收集整理的MySQL中的分析表、检查表与优化表如何操作?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JECloud快速入门手册_【数据字典】
- 下一篇: 终端应用变身文件 MD5/SHA1 校验