1. 程式人生 > 資料庫 >優化InnoDB表BLOB,TEXT列的儲存效率

優化InnoDB表BLOB,TEXT列的儲存效率

首先,介紹下關於MySQL InnoDB引擎儲存格式的幾個要點:

1、InnoDB可以選擇使用共享表空間或者是獨立表空間方式,建議使用獨立表空間,便於管理、維護。啟用 innodb_file_per_table 選項,5.5以後可以線上動態修改生效,並且執行 ALTER TABLE xx ENGINE = InnoDB 將現有錶轉成獨立表空間,早於5.5的版本,修改完這個選項後,需要重啟才能生效。

2、InnoDB的data page預設16KB,5.6版本以後,新增選項 innodb_page_size 可以修改,在5.6以前的版本,只能修改原始碼重新編譯,但並不推薦修改這個配置,除非你非常清楚它有什麼優缺點。

3、InnoDB的data page在有新資料寫入時,會預留1/16的空間,預留出來的空間可用於後續的新紀錄寫入,減少頻繁的新增data page的開銷。

4、每個data page,至少需要儲存2行記錄。因此理論上行記錄最大長度為8KB,但事實上應該更小,因為還有一些InnoDB內部資料結構要儲存。

5、受限於InnoDB儲存方式,如果資料是順序寫入的話,最理想的情況下,data page的填充率是15/16,但一般沒辦法保證完全的順序寫入,因此,data page的填充率一般是1/2到15/16。因此每個InnoDB表都最好要有一個自增列作為主鍵,使得新紀錄寫入儘可能是順序的。

6、當data page填充率不足1/2時,InnoDB會進行收縮,釋放空閒空間。

7、MySQL 5.6版本的InnoDB引擎當前支援COMPACTREDUNDANTDYNAMICCOMPRESSED四種格式,預設是COMPACT格式,COMPRESSED用的很少且不推薦(見下一條),如果需要用到壓縮特性的話,可以直接考慮TokuDB引擎。

8、COMPACT行格式相比REDUNDANT,大概能節省20%的儲存空間,COMPRESSED相比COMPACT大概能節省50%的儲存空間,但會導致TPS下降了90%。因此強烈不推薦使用COMPRESSED行格式。

9、當行格式為DYNAMIC或COMPRESSED時,TEXT/BLOB之類的長列(long column,也有可能是其他較長的列,不一定只有TEXT/BLOB型別,看具體情況)會完全儲存在一個獨立的data page裡,聚集索引頁中只使用20位元組的指標指向新的page,這就是所謂的off-page,類似ORACLE的行遷移,磁碟空間浪費較嚴重,且I/O效能也較差。因此,強烈不建議使用BLOB、TEXT、超過255長度的VARCHAR列型別。

10、當InnoDB的檔案格式(innodb_file_format)設定為Antelope,並且行格式為COMPACT 或 REDUNDANT 時,BLOB、TEXT或者長VARCHAR列只會將其前768位元組儲存在聚集索頁中(最大768位元組的作用是便於建立字首索引/prefix index),其餘更多的內容儲存在額外的page裡,哪怕只是多了一個位元組。因此,所有列長度越短越好。

11、在off-page中儲存的BLOB、TEXT或者長VARCHAR列的page是獨享的,不能共享。因此強烈不建議在一個表中使用多個長列。

綜上,如果在實際業務中,確實需要在InnoDB表中儲存BLOB、TEXT、長VARCHAR列時,有下面幾點建議:

1、儘可能將所有資料序列化、壓縮之後,儲存在同一個列裡,避免發生多次off-page。

2、實際最大儲存長度低於255的列,轉成VARCHAR或者CHAR型別(如果是變長資料二者沒區別,如果是定長資料,則使用CHAR型別)。

3、如果無法將所有列整合到一個列,可以退而求其次,根據每個列最大長度進行排列組合後拆分成多個子表,儘量是的每個子表的總行長度小於8KB,減少發生off-page的頻率。

4、上述建議是在data page為預設的16KB前提下,如果修改成8KB或者其他大小,請自行根據上述理論進行測試,找到最合適的值。

5、字元型列長度小於255時,無論採用CHAR還是VARCHAR來儲存,或者把VARCHAR列長度定義為255,都不會導致實際表空間增大。

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對我們的支援。如果你想了解更多相關內容請檢視下面相關連結