mysql存量表數據碎片與索引碎片優化

打工人

背景

最近領導分配了個任務,測試sit環境一些功能相比之前慢了許多,需要優化一下。

問題排查過程

瀏覽器F12查看相關接口的響應,看到底是哪個接口反應慢,根據互聯網的要求,頁面3秒還沒有顯示出來,用戶體驗會非常差。

查看相關代碼的提交時間,這些代碼一上線就沒有改動過,由此以我三年職業生涯的經驗推斷,可能是接口相關數據庫表設計不合理或者需要優化導致的問題,因而該篇文章由此誕生!

數據庫單表優化步驟

設計表時:1.選擇合適的字段類型

                   2.創建高性能索引

運維期間: 1.慢sql優化

                   2.mysql參數調優

                   3.數據碎片與索引碎片優化

之前我已做過數據庫部分優化,今天我們所採用的的優化方案是:數據碎片與索引碎片優化

Q:爲什麼會產生數據碎片與索引碎片呢?

A:由於表記錄delete後,只是在相應記錄上表示該記錄被刪除出,表空間沒有釋放從而導致數據碎片和索引碎片,佔用服務器存儲空間和影響索引的效率。

mysql引擎:

          MyISAM引擎: 數據儲存在MYD文件中,索引儲存在MYI文件中

          InnoDB引擎:frm文件存儲表結構,idb文件儲存索引和數據

 

數據碎片優化步驟

查看ide庫下需要優化的相關表sql:

select table_name,data_free from information_schema.tables where table_schema='ide' order by a.data_free desc;可以看到每個表的數據碎片分別是多少,如圖所示:

1

我們可以看到:rdos_engine_job_cache表的數據碎片比較多,可以清理一下

查看清理前表相關文件的大小,數據和索引文件是49452,如圖所示:

2

也可以用sql查詢:數據大小如上上圖的data_length,和data_free之和。

索引大小:show index from rdos_engine_job_cache;

Cardinality:索引中唯一值的數目的估計值。通過運行ANALYZE TABLE或myisamchk -a可以更新。基數根據被存儲爲整數的統計數據來計數,所以即使對於小型表,該值也沒有必要是精確的。基數越大,當進行聯合時,MySQL使用該索引的機會就越大。

相關字段值老鐵們可以自行百度。

注意:在OPTIMIZE TABLE運行過程中,MySQL會鎖定表。

對於myisam可以直接使用 optimize table table.name, 當是InnoDB引擎時,會報“Table does not support optimize, doing recreate + analyze instead”,一般情況下,由myisam轉成innodb,會用alter table table.name engine='innodb'進行轉換,優化也可以用這個。所以當是InnoDB引擎時我們就用alter table table.name engine='innodb'來代替optimize做優化就可以。

我們的表用的是Innodb引擎,執行命令:alter table rdos_engine_job_cache engine='innodb';如圖所示:

由圖可以看到清理前後的對比:表空間確實釋放了不少

索引碎片優化步驟

Analyze Table 

MySQL 的Optimizer(優化元件)在優化SQL語句時,首先需要收集一些相關信息,其中就包括表的cardinality(可以翻譯爲“散列程度”),它表示某個索引對應的列包含多少個不同的值——如果cardinality大大少於數據的實際散列程度,那麼索引就基本失效了。 
我們可以使用SHOW INDEX語句來查看索引的散列程度: 

SHOW INDEX FROM PLAYERS; 

TABLE   KEY_NAME COLUMN_NAME CARDINALITY 
------- -------- ----------- ----------- 
PLAYERS PRIMARY PLAYERNO             14 

因爲此時PLAYER表中不同的PLAYERNO數量遠遠多於14,索引基本失效。 
下面我們通過Analyze Table語句來修復索引: 

ANALYZE TABLE PLAYERS; 
SHOW INDEX FROM PLAYERS; 
結果是: 
TABLE   KEY_NAME COLUMN_NAME CARDINALITY 
------- -------- ----------- ----------- 
PLAYERS PRIMARY PLAYERNO           1000 

此時索引已經修復,查詢效率大大提高。 

需要注意的是,如果開啓了binlog,那麼Analyze Table的結果也會寫入binlog,我們可以在analyze和table之間添加關鍵字local取消寫入。 






















 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章