MySQL中怎麼進行大文字儲存壓縮
前面提到,我們有個雲端文檔專案的快照內容是直接儲存到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引擎頁資料超出16kb怎麼辦?
我們都知道innodb的頁塊預設大小為16k,如果表中一行資料長度超出了16k,就會出現行溢出,溢出的行是存放在另外的地方(uncompress blob page)。由於innodb採用叢集索引把資料存放起來,即B Tree結構,因此每個頁塊中至少有兩行數據,否則就失去了B Tree的意義,這樣就得出一行資料最大的長度限制為8k (大字段在數據頁會儲存768個字節數據,剩餘的數據溢出到另外的頁中,數據頁還有20個字節記錄溢出頁的地址)
- 對dynamic 格式來說,如果大物件欄位(text/blob)儲存資料大小小於40 位元組,那麼全部放在資料頁,剩餘的場景,資料頁只保留一個20 位元組的指標指向溢出頁。這種場景下,如果每個大物件欄位保存的資料小於 40 個位元組,也就和 varchar(40),效果一樣。
- innodb-row-format-dynamic:dev.mysql.com/doc/refman/…
Linux 稀疏檔案& 空洞
- 稀疏檔案(Sparse File):稀疏檔案與其他普通檔案基本上相同,差別在於檔案中的部分資料全為0,且這部分資料不佔用磁碟空間
- 檔案空洞:檔案位移量可以大於檔案的實際長度(位於檔案中但未被寫過的位元組設為0),空洞是否佔用磁碟空間由作業系統決定
#檔案空洞部分不佔用磁碟空間、檔案所佔用的磁碟空間仍然是連續的
innodb提供的壓縮方案
頁面壓縮
適用場景:由於資料量太大,磁碟空間不足,負載主要體現在IO上,而伺服器的CPU又有比較多的餘裕的場景。
1)COMPRESS頁壓縮
相關文件:dev.mysql.com/doc/refman/…
- 在MySQL5.7版本之前就提供的頁壓縮功能,在建立表格時指定ROW_FORMAT = COMPRESS,並透過KEY_BLOCK_SIZE 設定壓縮頁的大小
- 存在設計上的缺陷,有可能會導致效能下降明顯,然後其設計初衷是為了提升效能,引入了「日誌即資料」的概念
- #對於壓縮頁的資料修改,並不會直接修改頁本身,而是將修改日誌儲存在這個頁中,這確實對資料的變更比較友好,不用每次修改都進行壓縮/解壓縮
- 對於資料的讀取,壓縮的資料是無法直接讀取的,所以這個演算法會在記憶體中保留一個解壓縮後的16K的頁,以便資料的讀取
- 這就導致了一個頁在緩衝池中可能會有兩個版本(壓縮版和非壓縮版),引發一個非常嚴重的問題,即緩衝池中能緩存的頁的數量大大的減少了,從而可能會導致資料庫的效能極大的下降
- #對於壓縮頁的資料修改,並不會直接修改頁本身,而是將修改日誌儲存在這個頁中,這確實對資料的變更比較友好,不用每次修改都進行壓縮/解壓縮
2)TPC(透明頁壓縮)
相關文件:dev. mysql.com/doc/refman/…
- 工作原理:寫入頁面時,使用指定的壓縮演算法對頁面進行壓縮,壓縮後寫入磁碟,其中透過打孔機制從頁面末端釋放空白(需要作業系統支援
空洞
特性) ALTER TABLE xxx COMPRESSION = ZLIB
可以啟用TPC頁壓縮功能,但這只是對後續增量資料進行壓縮,如果預期對整個表進行壓縮,則需要執行OPTIMIZE TABLE xxx
實作過程:一個壓縮頁在緩衝池中都是一個16K的非壓縮頁,只有在資料刷盤的時候,會進行一次壓縮,壓縮後剩餘的空間會用0x00 填滿,利用檔案系統的空洞特性(hole punch)對檔案進行裁剪,釋放0x00 佔用的稀疏空間
- TPC雖好,但它依賴作業系統的Hole Punch 特性,且裁剪後的檔案大小需要和檔案系統區塊大小對齊( 4K)。即假如壓縮後的頁大小是9K,那麼實際佔用的空間是12K
列壓縮
MySQL目前沒有直接針對列壓縮的方案,有一個曲線救國的方法,就是在業務層使用MySQL提供的壓縮和解壓函數來針對列進行壓縮和解壓操作。也就是如果需要對某一列做壓縮,在寫入時呼叫COMPRESS
函數對那個列的內容進行壓縮,讀取的時候,使用UNCOMPRESS
函數對壓縮過的數據進行解壓縮。
- 使用場景:針對表中某些列資料長度比較大的情況,一般是varchar、text、blob、json等資料型別
- 相關函數:
- 壓縮函數:
COMPRESS()
- 解壓縮函數:
UNCOMPRESS()
- 字串長度函數:
LENGTH()
- 未解壓縮字串長度函數:
UNCOMPRESSED_LENGTH()
##測試: - 壓縮函數:
- 插入資料:
- insert into xxx (content) values (compress('xxx....'))
- 讀取壓縮的資料:
select c_id, uncompressed_length(c_content) uncompress_len, length(c_content) compress_len from xxx
- insert into xxx (content) values (compress('xxx....'))
#
为什么innodb提供的都是基于页面的压缩技术?
- 记录压缩:每次读写记录的时候,都要进行压缩或解压,过度依赖CPU的计算能力,性能相对会比较差
- 表空间压缩:压缩效率高,但要求表空间文件是静态不增长的,这对于我们大部分的场景都是不适用的
- 页面压缩:既能提升效率,又能在性能中取得一定的平衡
总结
- 对于一些性能不敏感的业务表,如日志表、监控表、告警表等,这些表只期望对存储空间进行优化,对性能的影响不是很关注,可以使用COMPRESS页压缩
- 对于一些比较核心的表,则比较推荐使用TPC压缩
- 列压缩过度依赖CPU,性能方面会稍差,且对业务有一定的改造成本,不够灵活,需要评估影响范围,做好切换的方案。好处是可以由业务端决定哪些数据需要压缩,并控制解压操作
- 对页面进行压缩,在业务侧不用进行什么改动,对线上完全透明,压缩方案也非常成熟
为什么要进行数据压缩?
- 由于处理器和高速缓存存储器的速度提高超过了磁盘存储设备,因此很多时候工作负载都是受限于磁盘I/O。数据压缩可以使数据占用更小的空间,可以节省磁盘I/O、减少网络I/O从而提高吞吐量,虽然会牺牲部分CPU资源作为代价
- 对于OLTP系统,经常进行update、delete、insert等操作,通过压缩表能够减少存储占用和IO消耗
- 压缩其实是一种平衡,并不一定是为了提升数据库的性能,这种平衡取决于解压缩带来的收益和开销之间的一种权衡,但压缩对存储空间来说,收益无疑是很大的
简单测试
innodb透明页压缩(TPC)
测试数据
1)创建表
- create table table_origin ( ...... ) comment '测试原表';
- create table table_compression_zlib ( ...... ) comment '测试压缩表_zlib' compression = 'zlib';
- create table table_compression_lz4 ( ...... ) comment '测试压缩表_lz4' compression = 'lz4';
2)往表中写入10w行测试数据
压缩率
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
:文件的实际大小,即磁盘上分配的空间量
压缩率:
- zlib:1320636416/3489660928 = 37.8%
- lz4:1566949376/3489660928 = 45%
耗时
- 循环插入10w条记录
- 原表:918275 ms
- zlib:878540 ms
- lz4:875259 ms
- 循环查询10w条记录
- 原表:332519 ms
- zlib:373387 ms
- lz4:343501 ms
【相关推荐:mysql视频教程】
以上是MySQL中怎麼進行大文字儲存壓縮的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

熱門話題

MySQL是一個開源的關係型數據庫管理系統。 1)創建數據庫和表:使用CREATEDATABASE和CREATETABLE命令。 2)基本操作:INSERT、UPDATE、DELETE和SELECT。 3)高級操作:JOIN、子查詢和事務處理。 4)調試技巧:檢查語法、數據類型和權限。 5)優化建議:使用索引、避免SELECT*和使用事務。

可以通過以下步驟打開 phpMyAdmin:1. 登錄網站控制面板;2. 找到並點擊 phpMyAdmin 圖標;3. 輸入 MySQL 憑據;4. 點擊 "登錄"。

使用 Navicat Premium 創建數據庫:連接到數據庫服務器並輸入連接參數。右鍵單擊服務器並選擇“創建數據庫”。輸入新數據庫的名稱和指定字符集和排序規則。連接到新數據庫並在“對象瀏覽器”中創建表。右鍵單擊表並選擇“插入數據”來插入數據。

MySQL是一種開源的關係型數據庫管理系統,主要用於快速、可靠地存儲和檢索數據。其工作原理包括客戶端請求、查詢解析、執行查詢和返回結果。使用示例包括創建表、插入和查詢數據,以及高級功能如JOIN操作。常見錯誤涉及SQL語法、數據類型和權限問題,優化建議包括使用索引、優化查詢和分錶分區。

選擇MySQL的原因是其性能、可靠性、易用性和社區支持。 1.MySQL提供高效的數據存儲和檢索功能,支持多種數據類型和高級查詢操作。 2.採用客戶端-服務器架構和多種存儲引擎,支持事務和查詢優化。 3.易於使用,支持多種操作系統和編程語言。 4.擁有強大的社區支持,提供豐富的資源和解決方案。

可在 Navicat 中通過以下步驟新建 MySQL 連接:打開應用程序並選擇“新建連接”(Ctrl N)。選擇“MySQL”作為連接類型。輸入主機名/IP 地址、端口、用戶名和密碼。 (可選)配置高級選項。保存連接並輸入連接名稱。

Redis 使用單線程架構,以提供高性能、簡單性和一致性。它利用 I/O 多路復用、事件循環、非阻塞 I/O 和共享內存來提高並發性,但同時存在並發性受限、單點故障和不適合寫密集型工作負載的局限性。

MySQL和SQL是開發者必備技能。 1.MySQL是開源的關係型數據庫管理系統,SQL是用於管理和操作數據庫的標準語言。 2.MySQL通過高效的數據存儲和檢索功能支持多種存儲引擎,SQL通過簡單語句完成複雜數據操作。 3.使用示例包括基本查詢和高級查詢,如按條件過濾和排序。 4.常見錯誤包括語法錯誤和性能問題,可通過檢查SQL語句和使用EXPLAIN命令優化。 5.性能優化技巧包括使用索引、避免全表掃描、優化JOIN操作和提升代碼可讀性。
