進步MySQL中InnoDB表BLOB列的存儲效力的教程。本站提示廣大學習愛好者:(進步MySQL中InnoDB表BLOB列的存儲效力的教程)文章只能為提供參考,不一定能成為您想要的結果。以下是進步MySQL中InnoDB表BLOB列的存儲效力的教程正文
起首,引見下關於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引擎以後支撐COMPACT、REDUNDANT、DYNAMIC、COMPRESSED四種格局,默許是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,都不會招致現實表空間增年夜;
6、普通在游戲范疇會用到比擬多的BLOB列類型,游戲界同業可以存眷下。
上面是測實驗證進程,有耐煩的同窗可以漸漸看:
# # 測試案例:InnoDB中長列存儲效力 # 測試場景描寫: # 在InnoDB表中存儲64KB的數據,比較各類分歧存儲方法# 每一個表寫入5000行記載,不雅察最初表空間文件年夜小比較 # #表0:一切數據存儲在一個BLOB列中 CREATE TABLE `t_longcol_0` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `longcol` blob NOT NULL COMMENT 'store all data in a blob column', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT; #響應的數據寫入存儲進程:mysp_longcol_0_ins() CREATE PROCEDURE `mysp_longcol_0_ins`( in cnt int ) begin set @i = 1; while @i < cnt do insert into t_longcol_0(longcol) select repeat('a',65535); set @i = @i + 1; end while; end; #表1:將64KB字節均勻存儲在9個列中 CREATE TABLE `t_longcol_1` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `longcol1` blob NOT NULL COMMENT 'store all data in 9 blob columns', `longcol2` blob NOT NULL, `longcol3` blob NOT NULL, `longcol4` blob NOT NULL, `longcol5` blob NOT NULL, `longcol6` blob NOT NULL, `longcol7` blob NOT NULL, `longcol8` blob NOT NULL, `longcol9` blob NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; #響應的數據寫入存儲進程:mysp_longcol_1_ins() CREATE PROCEDURE `mysp_longcol_1_ins`( in cnt int ) begin set @i = 1; while @i < cnt do insert into t_longcol_1(longcol1,longcol2,longcol3,longcol4,longcol5,longcol6,longcol7,longcol8,longcol9) select repeat('a',7500), repeat('a',7500), repeat('a',7500), repeat('a',7500), repeat('a',7500), repeat('a',7500), repeat('a',7500), repeat('a',7500), repeat('a',5535); set @i = @i + 1; end while; end; #表2:將64KB數據團圓存儲在多個BLOB列中 CREATE TABLE `t_longcol_2` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `longcol1` blob NOT NULL COMMENT 'store 100 bytes data', `longcol2` blob NOT NULL COMMENT 'store 100 bytes data', `longcol3` blob NOT NULL COMMENT 'store 100 bytes data', `longcol4` blob NOT NULL COMMENT 'store 100 bytes data', `longcol5` blob NOT NULL COMMENT 'store 100 bytes data', `longcol6` blob NOT NULL COMMENT 'store 255 bytes data', `longcol7` blob NOT NULL COMMENT 'store 368 bytes data', `longcol8` blob NOT NULL COMMENT 'store 496 bytes data', `longcol9` blob NOT NULL COMMENT 'store 512 bytes data', `longcol10` blob NOT NULL COMMENT 'store 640 bytes data', `longcol11` blob NOT NULL COMMENT 'store 768 bytes data', `longcol12` blob NOT NULL COMMENT 'store 912 bytes data', `longcol13` blob NOT NULL COMMENT 'store 1024 bytes data', `longcol14` blob NOT NULL COMMENT 'store 2048 bytes data', `longcol15` blob NOT NULL COMMENT 'store 3082 bytes data', `longcol16` blob NOT NULL COMMENT 'store 4096 bytes data', `longcol17` blob NOT NULL COMMENT 'store 8192 bytes data', `longcol18` blob NOT NULL COMMENT 'store 16284 bytes data', `longcol19` blob NOT NULL COMMENT 'store 20380 bytes data', `longcol20` blob NOT NULL COMMENT 'store 5977 bytes data', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; #響應的數據寫入存儲進程:mysp_longcol_1_ins() CREATE PROCEDURE `mysp_longcol_1_ins`( in cnt int ) begin set @i = 1; while @i < cnt do insert into t_longcol_2(longcol1,longcol2,longcol3,longcol4,longcol5,longcol6,longcol7,longcol8,longcol9,longcol10, longcol11,longcol12,longcol13,longcol14,longcol15,longcol16,longcol17,longcol18,longcol19,longcol20) select repeat('a',100), repeat('a',100), repeat('a',100), repeat('a',100), repeat('a',100), repeat('a',256), repeat('a',368), repeat('a',496), repeat('a',512), repeat('a',640), repeat('a',768), repeat('a',912), repeat('a',1024), repeat('a',2048), repeat('a',3082), repeat('a',4096), repeat('a',8192), repeat('a',16284), repeat('a',20380), repeat('a',5977); set @i = @i + 1; end while; end; #表3:將64KB數據團圓存儲在多個CHAR、VARCHAR、BLOB列中 CREATE TABLE `t_longcol_3` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `longcol1` char(100) NOT NULL DEFAULT '' COMMENT 'store 100 bytes data', `longcol2` char(100) NOT NULL DEFAULT '' COMMENT 'store 100 bytes data', `longcol3` char(100) NOT NULL DEFAULT '' COMMENT 'store 100 bytes data', `longcol4` char(100) NOT NULL DEFAULT '' COMMENT 'store 100 bytes data', `longcol5` char(100) NOT NULL DEFAULT '' COMMENT 'store 100 bytes data', `longcol6` varchar(256) NOT NULL DEFAULT '' COMMENT 'store 255 bytes data', `longcol7` varchar(368) NOT NULL DEFAULT '' COMMENT 'store 368 bytes data', `longcol8` varchar(496) NOT NULL DEFAULT '' COMMENT 'store 496 bytes data', `longcol9` varchar(512) NOT NULL DEFAULT '' COMMENT 'store 512 bytes data', `longcol10` varchar(640) NOT NULL DEFAULT '' COMMENT 'store 640 bytes data', `longcol11` varchar(768) NOT NULL DEFAULT '' COMMENT 'store 768 bytes data', `longcol12` varchar(912) NOT NULL DEFAULT '' COMMENT 'store 912 bytes data', `longcol13` varchar(1024) NOT NULL DEFAULT '' COMMENT 'store 1024 bytes data', `longcol14` varchar(2048) NOT NULL DEFAULT '' COMMENT 'store 2048 bytes data', `longcol15` varchar(3082) NOT NULL DEFAULT '' COMMENT 'store 3082 bytes data', `longcol16` varchar(4096) NOT NULL DEFAULT '' COMMENT 'store 4096 bytes data', `longcol17` blob NOT NULL COMMENT 'store 8192 bytes data', `longcol18` blob NOT NULL COMMENT 'store 16284 bytes data', `longcol19` blob NOT NULL COMMENT 'store 20380 bytes data', `longcol20` varchar(5977) NOT NULL DEFAULT '' COMMENT 'store 5977 bytes data', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; #響應的數據寫入存儲進程:mysp_longcol_3_ins() CREATE PROCEDURE `mysp_longcol_1_ins`( in cnt int ) begin set @i = 1; while @i < cnt do insert into t_longcol_3(longcol1,longcol2,longcol3,longcol4,longcol5,longcol6,longcol7,longcol8,longcol9,longcol10, longcol11,longcol12,longcol13,longcol14,longcol15,longcol16,longcol17,longcol18,longcol19,longcol20) select repeat('a',100), repeat('a',100), repeat('a',100), repeat('a',100), repeat('a',100), repeat('a',256), repeat('a',368), repeat('a',496), repeat('a',512), repeat('a',640), repeat('a',768), repeat('a',912), repeat('a',1024), repeat('a',2048), repeat('a',3082), repeat('a',4096), repeat('a',8192), repeat('a',16284), repeat('a',20380), repeat('a',5977); set @i = @i + 1; end while; end; #表4:將64KB數據團圓存儲在多個VARCHAR、BLOB列中,比較t_longcol_3中幾個列是CHAR的情形 CREATE TABLE `t_longcol_4` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `longcol1` varchar(100) NOT NULL DEFAULT '' COMMENT 'store 100 bytes data', `longcol2` varchar(100) NOT NULL DEFAULT '' COMMENT 'store 100 bytes data', `longcol3` varchar(100) NOT NULL DEFAULT '' COMMENT 'store 100 bytes data', `longcol4` varchar(100) NOT NULL DEFAULT '' COMMENT 'store 100 bytes data', `longcol5` varchar(100) NOT NULL DEFAULT '' COMMENT 'store 100 bytes data', `longcol6` varchar(256) NOT NULL DEFAULT '' COMMENT 'store 255 bytes data', `longcol7` varchar(368) NOT NULL DEFAULT '' COMMENT 'store 368 bytes data', `longcol8` varchar(496) NOT NULL DEFAULT '' COMMENT 'store 496 bytes data', `longcol9` varchar(512) NOT NULL DEFAULT '' COMMENT 'store 512 bytes data', `longcol10` varchar(640) NOT NULL DEFAULT '' COMMENT 'store 640 bytes data', `longcol11` varchar(768) NOT NULL DEFAULT '' COMMENT 'store 768 bytes data', `longcol12` varchar(912) NOT NULL DEFAULT '' COMMENT 'store 912 bytes data', `longcol13` varchar(1024) NOT NULL DEFAULT '' COMMENT 'store 1024 bytes data', `longcol14` varchar(2048) NOT NULL DEFAULT '' COMMENT 'store 2048 bytes data', `longcol15` varchar(3082) NOT NULL DEFAULT '' COMMENT 'store 3082 bytes data', `longcol16` varchar(4096) NOT NULL DEFAULT '' COMMENT 'store 4096 bytes data', `longcol17` blob NOT NULL COMMENT 'store 8192 bytes data', `longcol18` blob NOT NULL COMMENT 'store 16284 bytes data', `longcol19` blob NOT NULL COMMENT 'store 20380 bytes data', `longcol20` varchar(5977) NOT NULL DEFAULT '' COMMENT 'store 5977 bytes data', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; #響應的數據寫入存儲進程:mysp_longcol_4_ins() CREATE PROCEDURE `mysp_longcol_1_ins`( in cnt int ) begin set @i = 1; while @i < cnt do insert into t_longcol_4(longcol1,longcol2,longcol3,longcol4,longcol5,longcol6,longcol7,longcol8,longcol9,longcol10, longcol11,longcol12,longcol13,longcol14,longcol15,longcol16,longcol17,longcol18,longcol19,longcol20) select repeat('a',100), repeat('a',100), repeat('a',100), repeat('a',100), repeat('a',100), repeat('a',256), repeat('a',368), repeat('a',496), repeat('a',512), repeat('a',640), repeat('a',768), repeat('a',912), repeat('a',1024), repeat('a',2048), repeat('a',3082), repeat('a',4096), repeat('a',8192), repeat('a',16284), repeat('a',20380), repeat('a',5977); set @i = @i + 1; end while; end; #表5:將64KB數據團圓存儲在多個VARCHAR、BLOB列中,和t_longcol_4比擬,變更在於後面的幾個列長度改成了255,但現實存儲長度照樣100字節 CREATE TABLE `t_longcol_5` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `longcol1` varchar(255) NOT NULL DEFAULT '' COMMENT 'store 100 bytes data', `longcol2` varchar(255) NOT NULL DEFAULT '' COMMENT 'store 100 bytes data', `longcol3` varchar(255) NOT NULL DEFAULT '' COMMENT 'store 100 bytes data', `longcol4` varchar(255) NOT NULL DEFAULT '' COMMENT 'store 100 bytes data', `longcol5` varchar(255) NOT NULL DEFAULT '' COMMENT 'store 100 bytes data', `longcol6` varchar(256) NOT NULL DEFAULT '' COMMENT 'store 255 bytes data', `longcol7` varchar(368) NOT NULL DEFAULT '' COMMENT 'store 368 bytes data', `longcol8` varchar(496) NOT NULL DEFAULT '' COMMENT 'store 496 bytes data', `longcol9` varchar(512) NOT NULL DEFAULT '' COMMENT 'store 512 bytes data', `longcol10` varchar(640) NOT NULL DEFAULT '' COMMENT 'store 640 bytes data', `longcol11` varchar(768) NOT NULL DEFAULT '' COMMENT 'store 768 bytes data', `longcol12` varchar(912) NOT NULL DEFAULT '' COMMENT 'store 912 bytes data', `longcol13` varchar(1024) NOT NULL DEFAULT '' COMMENT 'store 1024 bytes data', `longcol14` varchar(2048) NOT NULL DEFAULT '' COMMENT 'store 2048 bytes data', `longcol15` varchar(3082) NOT NULL DEFAULT '' COMMENT 'store 3082 bytes data', `longcol16` varchar(4096) NOT NULL DEFAULT '' COMMENT 'store 4096 bytes data', `longcol17` blob NOT NULL COMMENT 'store 8192 bytes data', `longcol18` blob NOT NULL COMMENT 'store 16284 bytes data', `longcol19` blob NOT NULL COMMENT 'store 20380 bytes data', `longcol20` varchar(5977) NOT NULL DEFAULT '' COMMENT 'store 5977 bytes data', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; #響應的數據寫入存儲進程:mysp_longcol_5_ins() CREATE PROCEDURE `mysp_longcol_1_ins`( in cnt int ) begin set @i = 1; while @i < cnt do insert into t_longcol_5(longcol1,longcol2,longcol3,longcol4,longcol5,longcol6,longcol7,longcol8,longcol9,longcol10, longcol11,longcol12,longcol13,longcol14,longcol15,longcol16,longcol17,longcol18,longcol19,longcol20) select repeat('a',100), repeat('a',100), repeat('a',100), repeat('a',100), repeat('a',100), repeat('a',256), repeat('a',368), repeat('a',496), repeat('a',512), repeat('a',640), repeat('a',768), repeat('a',912), repeat('a',1024), repeat('a',2048), repeat('a',3082), repeat('a',4096), repeat('a',8192), repeat('a',16284), repeat('a',20380), repeat('a',5977); set @i = @i + 1; end while; end; #從上面開端,參考第3條建議停止分表,每一個表一切列長度總和 #分表1,行最年夜長度 100 + 100 + 100 + 100 + 100 + 255 + 368 + 496 + 512 + 640 + 768 + 912 + 3082 = 7533 字節 CREATE TABLE `t_longcol_51` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `longcol1` varchar(255) NOT NULL DEFAULT '' COMMENT 'store 100 bytes data', `longcol2` varchar(255) NOT NULL DEFAULT '' COMMENT 'store 100 bytes data', `longcol3` varchar(255) NOT NULL DEFAULT '' COMMENT 'store 100 bytes data', `longcol4` varchar(255) NOT NULL DEFAULT '' COMMENT 'store 100 bytes data', `longcol5` varchar(255) NOT NULL DEFAULT '' COMMENT 'store 100 bytes data', `longcol6` varchar(256) NOT NULL DEFAULT '' COMMENT 'store 255 bytes data', `longcol7` varchar(368) NOT NULL DEFAULT '' COMMENT 'store 368 bytes data', `longcol8` varchar(496) NOT NULL DEFAULT '' COMMENT 'store 496 bytes data', `longcol9` varchar(512) NOT NULL DEFAULT '' COMMENT 'store 512 bytes data', `longcol10` varchar(640) NOT NULL DEFAULT '' COMMENT 'store 640 bytes data', `longcol11` varchar(768) NOT NULL DEFAULT '' COMMENT 'store 768 bytes data', `longcol12` varchar(912) NOT NULL DEFAULT '' COMMENT 'store 912 bytes data', `longcol15` varchar(3082) NOT NULL DEFAULT '' COMMENT 'store 3082 bytes data', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; #分表2,行最年夜長度 1024 + 2048 + 4096 = 7168 字節 CREATE TABLE `t_longcol_52` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `longcol13` varchar(1024) NOT NULL DEFAULT '' COMMENT 'store 1024 bytes data', `longcol14` varchar(2048) NOT NULL DEFAULT '' COMMENT 'store 2048 bytes data', `longcol16` varchar(4096) NOT NULL DEFAULT '' COMMENT 'store 4096 bytes data', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; #分表3,行最年夜長度 8192 字節 CREATE TABLE `t_longcol_53` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `longcol17` blob NOT NULL COMMENT 'store 8192 bytes data', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; #分表4,行最年夜長度 16284 + 20380 = 36664 字節 CREATE TABLE `t_longcol_54` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `longcol18` blob NOT NULL COMMENT 'store 16284 bytes data', `longcol19` blob NOT NULL COMMENT 'store 20380 bytes data', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; #分表5,行最年夜長度 5977 + 4 = 5981 字節 CREATE TABLE `t_longcol_55` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `longcol20` varchar(5977) NOT NULL DEFAULT '' COMMENT 'store 5977 bytes data', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; #響應的數據寫入存儲進程:mysp_longcol_51_ins() CREATE PROCEDURE `mysp_longcol_51_ins`( in cnt int ) begin set @i = 1; while @i < cnt do insert into t_longcol_51(longcol1,longcol2,longcol3,longcol4,longcol5,longcol6,longcol7,longcol8,longcol9,longcol10, longcol11,longcol12,longcol15) select repeat('a',100), repeat('a',100), repeat('a',100), repeat('a',100), repeat('a',100), repeat('a',256), repeat('a',368), repeat('a',496), repeat('a',512), repeat('a',640), repeat('a',768), repeat('a',912), repeat('a',3082); insert into t_longcol_52(longcol13,longcol14,longcol16) select repeat('a',1024), repeat('a',2048), repeat('a',4096); insert into t_longcol_53(longcol17) select repeat('a',8192); insert into t_longcol_54(longcol18,longcol19) select repeat('a',16284), repeat('a',20380); insert into t_longcol_55(longcol20) select repeat('a',5977); set @i = @i + 1; end while; end;
上述各個測試表都寫入5000行記載後,再來比較下其表空間文件年夜小,和重整表空間後的年夜小,不雅察碎片率。具體比較見下:
最初一種分表方法中,5個子表的表空間文件年夜小總和是 40960 + 40960 + 98304 + 286720 + 40960 = 507904 字節。
可以看到,這類方法的總年夜小和原始表年夜小差距最小,其他幾種存儲方法都比這個來的年夜。