前面提到,我們有個雲端文檔專案的快照內容是直接儲存到db的,屬於大文本存儲,文檔快照的內容欄位大部分都是kb級別,部分甚至到MB級別。目前對於資料的讀取,已經進行了CDN快取最佳化(靜態資源快取利器-CDN),對於資料的寫入和儲存還有待最佳化,如果可以透過一些壓縮演算法在大文字進行壓縮存儲,可以大幅節省DB的儲存空間,緩解DB的I/O壓力。
select table_name as '表名', table_rows as '记录数', truncate(data_length/1024/1024, 2) as '数据容量(MB)', truncate(index_length/1024/1024, 2) as '索引容量(MB)', truncate(DATA_FREE/1024/1024, 2) as '碎片占用(MB)' from information_schema.tables where table_schema=${数据库名} order by data_length desc, index_length desc;
我們都知道innodb的頁塊預設大小為16k,如果表中一行資料長度超出了16k,就會出現行溢出,溢出的行是存放在另外的地方(uncompress blob page)。由於innodb採用叢集索引把資料存放起來,即B Tree結構,因此每個頁塊中至少有兩行數據,否則就失去了B Tree的意義,這樣就得出一行資料最大的長度限制為8k (大字段在數據頁會儲存768個字節數據,剩餘的數據溢出到另外的頁中,數據頁還有20個字節記錄溢出頁的地址)
#檔案空洞部分不佔用磁碟空間、檔案所佔用的磁碟空間仍然是連續的
適用場景:由於資料量太大,磁碟空間不足,負載主要體現在IO上,而伺服器的CPU又有比較多的餘裕的場景。
相關文件:dev.mysql.com/doc/refman/…
相關文件:dev. mysql.com/doc/refman/…
空洞
特性)ALTER TABLE xxx COMPRESSION = ZLIB
可以啟用TPC頁壓縮功能,但這只是對後續增量資料進行壓縮,如果預期對整個表進行壓縮,則需要執行OPTIMIZE TABLE xxx
實作過程:一個壓縮頁在緩衝池中都是一個16K的非壓縮頁,只有在資料刷盤的時候,會進行一次壓縮,壓縮後剩餘的空間會用0x00 填滿,利用檔案系統的空洞特性(hole punch)對檔案進行裁剪,釋放0x00 佔用的稀疏空間
MySQL目前沒有直接針對列壓縮的方案,有一個曲線救國的方法,就是在業務層使用MySQL提供的壓縮和解壓函數來針對列進行壓縮和解壓操作。也就是如果需要對某一列做壓縮,在寫入時呼叫COMPRESS
函數對那個列的內容進行壓縮,讀取的時候,使用UNCOMPRESS
函數對壓縮過的數據進行解壓縮。
COMPRESS()
UNCOMPRESS()
LENGTH()
UNCOMPRESSED_LENGTH()
select c_id, uncompressed_length(c_content) uncompress_len, length(c_content) compress_len from xxx
#
SELECT NAME, FS_BLOCK_SIZE, FILE_SIZE, ALLOCATED_SIZE FROM information_schema.INNODB_TABLESPACES WHERE NAME like 'test_compress%';
FS_BLOCK_SIZE
:文件系统块大小,也就是打孔使用的单位大小FILE_SIZE
:文件的表观大小,表示文件的最大大小,未压缩ALLOCATED_SIZE
:文件的实际大小,即磁盘上分配的空间量压缩率:
【相关推荐:mysql视频教程】
以上是MySQL中怎麼進行大文字儲存壓縮的詳細內容。更多資訊請關注PHP中文網其他相關文章!