首页 > 数据库 > MySQL > 正文

提高MySQL中InnoDB表BLOB列的存储效率的教程

2024-07-24 13:07:10
字体:
来源:转载
供稿:网友

这篇文章主要介绍了提高MySQL中InnoDB表BLOB列的存储效率的教程,InnoDB的优化在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引擎当前支持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列类型,游戏界同行可以关注下。

下面是测试验证过程,有耐心的同学可以慢慢看:

  1. # 测试案例:InnoDB中长列存储效率 
  2. # 测试场景描述: 
  3. # 在InnoDB表中存储64KB的数据,对比各种不同存储方式 # 每个表写入5000行记录,观察最后表空间文件大小对比 
  4.  
  5. #表0:所有数据存储在一个BLOB列中 
  6. CREATE TABLE `t_longcol_0` ( 
  7. `id` int(10) unsigned NOT NULL AUTO_INCREMENT, 
  8. `longcol` blob NOT NULL COMMENT 'store all data in a blob column'
  9. PRIMARY KEY (`id`) 
  10. ) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT; 
  11.  
  12. #相应的数据写入存储过程:mysp_longcol_0_ins() 
  13. CREATE PROCEDURE `mysp_longcol_0_ins`( in cnt int ) 
  14. begin 
  15. set @i = 1; 
  16. while @i < cnt do 
  17. insert into t_longcol_0(longcol) select repeat('a',65535); 
  18. set @i = @i + 1; 
  19. end while; 
  20. end
  21.  
  22. #表1:将64KB字节平均存储在9个列中 
  23. CREATE TABLE `t_longcol_1` ( 
  24. `id` int(10) unsigned NOT NULL AUTO_INCREMENT, 
  25. `longcol1` blob NOT NULL COMMENT 'store all data in 9 blob columns'
  26. `longcol2` blob NOT NULL
  27. `longcol3` blob NOT NULL
  28. `longcol4` blob NOT NULL
  29. `longcol5` blob NOT NULL
  30. `longcol6` blob NOT NULL
  31. `longcol7` blob NOT NULL
  32. `longcol8` blob NOT NULL
  33. `longcol9` blob NOT NULL
  34. PRIMARY KEY (`id`) 
  35. ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 
  36.  
  37. #相应的数据写入存储过程:mysp_longcol_1_ins() 
  38. CREATE PROCEDURE `mysp_longcol_1_ins`( in cnt int ) 
  39. begin 
  40. set @i = 1; 
  41. while @i < cnt do 
  42. insert into t_longcol_1(longcol1,longcol2,longcol3,longcol4,longcol5,longcol6,longcol7,longcol8,longcol9) select 
  43. repeat('a',7500), 
  44. repeat('a',7500), 
  45. repeat('a',7500), 
  46. repeat('a',7500), 
  47. repeat('a',7500), 
  48. repeat('a',7500), 
  49. repeat('a',7500), 
  50. repeat('a',7500), 
  51. repeat('a',5535); 
  52. set @i = @i + 1; 
  53. end while; 
  54. end
  55.  
  56. #表2:将64KB数据离散存储在多个BLOB列中 
  57. CREATE TABLE `t_longcol_2` ( 
  58. `id` int(10) unsigned NOT NULL AUTO_INCREMENT, 
  59. `longcol1` blob NOT NULL COMMENT 'store 100 bytes data'
  60. `longcol2` blob NOT NULL COMMENT 'store 100 bytes data'
  61. `longcol3` blob NOT NULL COMMENT 'store 100 bytes data'
  62. `longcol4` blob NOT NULL COMMENT 'store 100 bytes data'
  63. `longcol5` blob NOT NULL COMMENT 'store 100 bytes data'
  64. `longcol6` blob NOT NULL COMMENT 'store 255 bytes data'
  65. `longcol7` blob NOT NULL COMMENT 'store 368 bytes data'
  66. `longcol8` blob NOT NULL COMMENT 'store 496 bytes data'
  67. `longcol9` blob NOT NULL COMMENT 'store 512 bytes data'
  68. `longcol10` blob NOT NULL COMMENT 'store 640 bytes data'
  69. `longcol11` blob NOT NULL COMMENT 'store 768 bytes data'
  70. `longcol12` blob NOT NULL COMMENT 'store 912 bytes data'
  71. `longcol13` blob NOT NULL COMMENT 'store 1024 bytes data'
  72. `longcol14` blob NOT NULL COMMENT 'store 2048 bytes data'
  73. `longcol15` blob NOT NULL COMMENT 'store 3082 bytes data'
  74. `longcol16` blob NOT NULL COMMENT 'store 4096 bytes data'
  75. `longcol17` blob NOT NULL COMMENT 'store 8192 bytes data'
  76. `longcol18` blob NOT NULL COMMENT 'store 16284 bytes data'
  77. `longcol19` blob NOT NULL COMMENT 'store 20380 bytes data'
  78. `longcol20` blob NOT NULL COMMENT 'store 5977 bytes data'
  79. PRIMARY KEY (`id`) 
  80. ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 
  81.  
  82. #相应的数据写入存储过程:mysp_longcol_1_ins() 
  83. CREATE PROCEDURE `mysp_longcol_1_ins`( in cnt int ) 
  84. begin 
  85. set @i = 1; 
  86. while @i < cnt do 
  87. insert into t_longcol_2(longcol1,longcol2,longcol3,longcol4,longcol5,longcol6,longcol7,longcol8,longcol9,longcol10, 
  88. longcol11,longcol12,longcol13,longcol14,longcol15,longcol16,longcol17,longcol18,longcol19,longcol20) select 
  89. repeat('a',100), 
  90. repeat('a',100), 
  91. repeat('a',100), 
  92. repeat('a',100), 
  93. repeat('a',100), 
  94. repeat('a',256), 
  95. repeat('a',368), 
  96. repeat('a',496), 
  97. repeat('a',512), 
  98. repeat('a',640), 
  99. repeat('a',768), 
  100. repeat('a',912), 
  101. repeat('a',1024), 
  102. repeat('a',2048), 
  103. repeat('a',3082), 
  104. repeat('a',4096), 
  105. repeat('a',8192), 
  106. repeat('a',16284), 
  107. repeat('a',20380), 
  108. repeat('a',5977); 
  109. set @i = @i + 1; 
  110. end while; 
  111. end
  112.  
  113. #表3:将64KB数据离散存储在多个CHARVARCHAR、BLOB列中 
  114. CREATE TABLE `t_longcol_3` ( 
  115. `id` int(10) unsigned NOT NULL AUTO_INCREMENT, 
  116. `longcol1` char(100) NOT NULL DEFAULT '' COMMENT 'store 100 bytes data'
  117. `longcol2` char(100) NOT NULL DEFAULT '' COMMENT 'store 100 bytes data'
  118. `longcol3` char(100) NOT NULL DEFAULT '' COMMENT 'store 100 bytes data'
  119. `longcol4` char(100) NOT NULL DEFAULT '' COMMENT 'store 100 bytes data'
  120. `longcol5` char(100) NOT NULL DEFAULT '' COMMENT 'store 100 bytes data'
  121. `longcol6` varchar(256) NOT NULL DEFAULT '' COMMENT 'store 255 bytes data'
  122. `longcol7` varchar(368) NOT NULL DEFAULT '' COMMENT 'store 368 bytes data'
  123. `longcol8` varchar(496) NOT NULL DEFAULT '' COMMENT 'store 496 bytes data'
  124. `longcol9` varchar(512) NOT NULL DEFAULT '' COMMENT 'store 512 bytes data'
  125. `longcol10` varchar(640) NOT NULL DEFAULT '' COMMENT 'store 640 bytes data'
  126. `longcol11` varchar(768) NOT NULL DEFAULT '' COMMENT 'store 768 bytes data'
  127. `longcol12` varchar(912) NOT NULL DEFAULT '' COMMENT 'store 912 bytes data'
  128. `longcol13` varchar(1024) NOT NULL DEFAULT '' COMMENT 'store 1024 bytes data'
  129. `longcol14` varchar(2048) NOT NULL DEFAULT '' COMMENT 'store 2048 bytes data'
  130. `longcol15` varchar(3082) NOT NULL DEFAULT '' COMMENT 'store 3082 bytes data'
  131. `longcol16` varchar(4096) NOT NULL DEFAULT '' COMMENT 'store 4096 bytes data'
  132. `longcol17` blob NOT NULL COMMENT 'store 8192 bytes data'
  133. `longcol18` blob NOT NULL COMMENT 'store 16284 bytes data'
  134. `longcol19` blob NOT NULL COMMENT 'store 20380 bytes data'
  135. `longcol20` varchar(5977) NOT NULL DEFAULT '' COMMENT 'store 5977 bytes data'
  136. PRIMARY KEY (`id`) 
  137. ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 
  138.  
  139. #相应的数据写入存储过程:mysp_longcol_3_ins() 
  140. CREATE PROCEDURE `mysp_longcol_1_ins`( in cnt int ) 
  141. begin 
  142. set @i = 1; 
  143. while @i < cnt do 
  144. insert into t_longcol_3(longcol1,longcol2,longcol3,longcol4,longcol5,longcol6,longcol7,longcol8,longcol9,longcol10, 
  145. longcol11,longcol12,longcol13,longcol14,longcol15,longcol16,longcol17,longcol18,longcol19,longcol20) select 
  146. repeat('a',100), 
  147. repeat('a',100), 
  148. repeat('a',100), 
  149. repeat('a',100), 
  150. repeat('a',100), 
  151. repeat('a',256), 
  152. repeat('a',368), 
  153. repeat('a',496), 
  154. repeat('a',512), 
  155. repeat('a',640), 
  156. repeat('a',768), 
  157. repeat('a',912), 
  158. repeat('a',1024), 
  159. repeat('a',2048), 
  160. repeat('a',3082), 
  161. repeat('a',4096), 
  162. repeat('a',8192), 
  163. repeat('a',16284), 
  164. repeat('a',20380), 
  165. repeat('a',5977); 
  166. set @i = @i + 1; 
  167. end while; 
  168. end
  169.  
  170. #表4:将64KB数据离散存储在多个VARCHAR、BLOB列中,对比t_longcol_3中几个列是CHAR的情况 
  171. CREATE TABLE `t_longcol_4` ( 
  172. `id` int(10) unsigned NOT NULL AUTO_INCREMENT, 
  173. `longcol1` varchar(100) NOT NULL DEFAULT '' COMMENT 'store 100 bytes data'
  174. `longcol2` varchar(100) NOT NULL DEFAULT '' COMMENT 'store 100 bytes data'
  175. `longcol3` varchar(100) NOT NULL DEFAULT '' COMMENT 'store 100 bytes data'
  176. `longcol4` varchar(100) NOT NULL DEFAULT '' COMMENT 'store 100 bytes data'
  177. `longcol5` varchar(100) NOT NULL DEFAULT '' COMMENT 'store 100 bytes data'
  178. `longcol6` varchar(256) NOT NULL DEFAULT '' COMMENT 'store 255 bytes data'
  179. `longcol7` varchar(368) NOT NULL DEFAULT '' COMMENT 'store 368 bytes data'
  180. `longcol8` varchar(496) NOT NULL DEFAULT '' COMMENT 'store 496 bytes data'
  181. `longcol9` varchar(512) NOT NULL DEFAULT '' COMMENT 'store 512 bytes data'
  182. `longcol10` varchar(640) NOT NULL DEFAULT '' COMMENT 'store 640 bytes data'
  183. `longcol11` varchar(768) NOT NULL DEFAULT '' COMMENT 'store 768 bytes data'
  184. `longcol12` varchar(912) NOT NULL DEFAULT '' COMMENT 'store 912 bytes data'
  185. `longcol13` varchar(1024) NOT NULL DEFAULT '' COMMENT 'store 1024 bytes data'
  186. `longcol14` varchar(2048) NOT NULL DEFAULT '' COMMENT 'store 2048 bytes data'
  187. `longcol15` varchar(3082) NOT NULL DEFAULT '' COMMENT 'store 3082 bytes data'
  188. `longcol16` varchar(4096) NOT NULL DEFAULT '' COMMENT 'store 4096 bytes data'
  189. `longcol17` blob NOT NULL COMMENT 'store 8192 bytes data'
  190. `longcol18` blob NOT NULL COMMENT 'store 16284 bytes data'
  191. `longcol19` blob NOT NULL COMMENT 'store 20380 bytes data'
  192. `longcol20` varchar(5977) NOT NULL DEFAULT '' COMMENT 'store 5977 bytes data'
  193. PRIMARY KEY (`id`) 
  194. ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 
  195.  
  196. #相应的数据写入存储过程:mysp_longcol_4_ins() 
  197. CREATE PROCEDURE `mysp_longcol_1_ins`( in cnt int ) 
  198. begin 
  199. set @i = 1; 
  200. while @i < cnt do 
  201. insert into t_longcol_4(longcol1,longcol2,longcol3,longcol4,longcol5,longcol6,longcol7,longcol8,longcol9,longcol10, 
  202. longcol11,longcol12,longcol13,longcol14,longcol15,longcol16,longcol17,longcol18,longcol19,longcol20) select 
  203. repeat('a',100), 
  204. repeat('a',100), 
  205. repeat('a',100), 
  206. repeat('a',100), 
  207. repeat('a',100), 
  208. repeat('a',256), 
  209. repeat('a',368), 
  210. repeat('a',496), 
  211. repeat('a',512), 
  212. repeat('a',640), 
  213. repeat('a',768), 
  214. repeat('a',912), 
  215. repeat('a',1024), 
  216. repeat('a',2048), 
  217. repeat('a',3082), 
  218. repeat('a',4096), 
  219. repeat('a',8192), 
  220. repeat('a',16284), 
  221. repeat('a',20380), 
  222. repeat('a',5977); 
  223. set @i = @i + 1; 
  224. end while; 
  225. end
  226.  
  227. #表5:将64KB数据离散存储在多个VARCHAR、BLOB列中,和t_longcol_4相比,变化在于前面的几个列长度改成了255,但实际存储长度还是100字节 
  228. CREATE TABLE `t_longcol_5` ( 
  229. `id` int(10) unsigned NOT NULL AUTO_INCREMENT, 
  230. `longcol1` varchar(255) NOT NULL DEFAULT '' COMMENT 'store 100 bytes data'
  231. `longcol2` varchar(255) NOT NULL DEFAULT '' COMMENT 'store 100 bytes data'
  232. `longcol3` varchar(255) NOT NULL DEFAULT '' COMMENT 'store 100 bytes data'
  233. `longcol4` varchar(255) NOT NULL DEFAULT '' COMMENT 'store 100 bytes data'
  234. `longcol5` varchar(255) NOT NULL DEFAULT '' COMMENT 'store 100 bytes data'
  235. `longcol6` varchar(256) NOT NULL DEFAULT '' COMMENT 'store 255 bytes data'
  236. `longcol7` varchar(368) NOT NULL DEFAULT '' COMMENT 'store 368 bytes data'
  237. `longcol8` varchar(496) NOT NULL DEFAULT '' COMMENT 'store 496 bytes data'
  238. `longcol9` varchar(512) NOT NULL DEFAULT '' COMMENT 'store 512 bytes data'
  239. `longcol10` varchar(640) NOT NULL DEFAULT '' COMMENT 'store 640 bytes data'
  240. `longcol11` varchar(768) NOT NULL DEFAULT '' COMMENT 'store 768 bytes data'
  241. `longcol12` varchar(912) NOT NULL DEFAULT '' COMMENT 'store 912 bytes data'
  242. `longcol13` varchar(1024) NOT NULL DEFAULT '' COMMENT 'store 1024 bytes data'
  243. `longcol14` varchar(2048) NOT NULL DEFAULT '' COMMENT 'store 2048 bytes data'
  244. `longcol15` varchar(3082) NOT NULL DEFAULT '' COMMENT 'store 3082 bytes data'
  245. `longcol16` varchar(4096) NOT NULL DEFAULT '' COMMENT 'store 4096 bytes data'
  246. `longcol17` blob NOT NULL COMMENT 'store 8192 bytes data'
  247. `longcol18` blob NOT NULL COMMENT 'store 16284 bytes data'
  248. `longcol19` blob NOT NULL COMMENT 'store 20380 bytes data'
  249. `longcol20` varchar(5977) NOT NULL DEFAULT '' COMMENT 'store 5977 bytes data'
  250. PRIMARY KEY (`id`) 
  251. ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 
  252.  
  253. #相应的数据写入存储过程:mysp_longcol_5_ins() 
  254. CREATE PROCEDURE `mysp_longcol_1_ins`( in cnt int ) 
  255. begin 
  256. set @i = 1; 
  257. while @i < cnt do 
  258. insert into t_longcol_5(longcol1,longcol2,longcol3,longcol4,longcol5,longcol6,longcol7,longcol8,longcol9,longcol10, 
  259. longcol11,longcol12,longcol13,longcol14,longcol15,longcol16,longcol17,longcol18,longcol19,longcol20) select 
  260. repeat('a',100), 
  261. repeat('a',100), 
  262. repeat('a',100), 
  263. repeat('a',100), 
  264. repeat('a',100), 
  265. repeat('a',256), 
  266. repeat('a',368), 
  267. repeat('a',496), 
  268. repeat('a',512), 
  269. repeat('a',640), 
  270. repeat('a',768), 
  271. repeat('a',912), 
  272. repeat('a',1024), 
  273. repeat('a',2048), 
  274. repeat('a',3082), 
  275. repeat('a',4096), 
  276. repeat('a',8192), 
  277. repeat('a',16284), 
  278. repeat('a',20380), 
  279. repeat('a',5977); 
  280. set @i = @i + 1; 
  281. end while; 
  282. end
  283.  
  284. #从下面开始,参考第3条建议进行分表,每个表所有列长度总和 
  285. #分表1,行最大长度 100 + 100 + 100 + 100 + 100 + 255 + 368 + 496 + 512 + 640 + 768 + 912 + 3082 = 7533 字节 
  286. CREATE TABLE `t_longcol_51` ( 
  287. `id` int(10) unsigned NOT NULL AUTO_INCREMENT, 
  288. `longcol1` varchar(255) NOT NULL DEFAULT '' COMMENT 'store 100 bytes data'
  289. `longcol2` varchar(255) NOT NULL DEFAULT '' COMMENT 'store 100 bytes data'
  290. `longcol3` varchar(255) NOT NULL DEFAULT '' COMMENT 'store 100 bytes data'
  291. `longcol4` varchar(255) NOT NULL DEFAULT '' COMMENT 'store 100 bytes data'
  292. `longcol5` varchar(255) NOT NULL DEFAULT '' COMMENT 'store 100 bytes data'
  293. `longcol6` varchar(256) NOT NULL DEFAULT '' COMMENT 'store 255 bytes data'
  294. `longcol7` varchar(368) NOT NULL DEFAULT '' COMMENT 'store 368 bytes data'
  295. `longcol8` varchar(496) NOT NULL DEFAULT '' COMMENT 'store 496 bytes data'
  296. `longcol9` varchar(512) NOT NULL DEFAULT '' COMMENT 'store 512 bytes data'
  297. `longcol10` varchar(640) NOT NULL DEFAULT '' COMMENT 'store 640 bytes data'
  298. `longcol11` varchar(768) NOT NULL DEFAULT '' COMMENT 'store 768 bytes data'
  299. `longcol12` varchar(912) NOT NULL DEFAULT '' COMMENT 'store 912 bytes data'
  300. `longcol15` varchar(3082) NOT NULL DEFAULT '' COMMENT 'store 3082 bytes data'
  301. PRIMARY KEY (`id`) 
  302. ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 
  303.  
  304. #分表2,行最大长度 1024 + 2048 + 4096 = 7168 字节 
  305. CREATE TABLE `t_longcol_52` ( 
  306. `id` int(10) unsigned NOT NULL AUTO_INCREMENT, 
  307. `longcol13` varchar(1024) NOT NULL DEFAULT '' COMMENT 'store 1024 bytes data'
  308. `longcol14` varchar(2048) NOT NULL DEFAULT '' COMMENT 'store 2048 bytes data'
  309. `longcol16` varchar(4096) NOT NULL DEFAULT '' COMMENT 'store 4096 bytes data'
  310. PRIMARY KEY (`id`) 
  311. ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 
  312.  
  313. #分表3,行最大长度 8192 字节 
  314. CREATE TABLE `t_longcol_53` ( 
  315. `id` int(10) unsigned NOT NULL AUTO_INCREMENT, 
  316. `longcol17` blob NOT NULL COMMENT 'store 8192 bytes data'
  317. PRIMARY KEY (`id`) 
  318. ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 
  319.  
  320. #分表4,行最大长度 16284 + 20380 = 36664 字节 
  321. CREATE TABLE `t_longcol_54` ( 
  322. `id` int(10) unsigned NOT NULL AUTO_INCREMENT, 
  323. `longcol18` blob NOT NULL COMMENT 'store 16284 bytes data'
  324. `longcol19` blob NOT NULL COMMENT 'store 20380 bytes data'
  325. PRIMARY KEY (`id`) 
  326. ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 
  327.  
  328. #分表5,行最大长度 5977 + 4 = 5981 字节 
  329. CREATE TABLE `t_longcol_55` ( 
  330. `id` int(10) unsigned NOT NULL AUTO_INCREMENT, 
  331. `longcol20` varchar(5977) NOT NULL DEFAULT '' COMMENT 'store 5977 bytes data'
  332. PRIMARY KEY (`id`) 
  333. ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 
  334.  
  335. #相应的数据写入存储过程:mysp_longcol_51_ins() 
  336. CREATE PROCEDURE `mysp_longcol_51_ins`( in cnt int ) 
  337. begin 
  338. set @i = 1; 
  339. while @i < cnt do 
  340. insert into t_longcol_51(longcol1,longcol2,longcol3,longcol4,longcol5,longcol6,longcol7,longcol8,longcol9,longcol10, 
  341. longcol11,longcol12,longcol15) select 
  342. repeat('a',100), 
  343. repeat('a',100), 
  344. repeat('a',100), 
  345. repeat('a',100), 
  346. repeat('a',100), 
  347. repeat('a',256), 
  348. repeat('a',368), 
  349. repeat('a',496), 
  350. repeat('a',512), 
  351. repeat('a',640), 
  352. repeat('a',768), 
  353. repeat('a',912), 
  354. repeat('a',3082); 
  355.  
  356. insert into t_longcol_52(longcol13,longcol14,longcol16) select 
  357. repeat('a',1024), 
  358. repeat('a',2048), 
  359. repeat('a',4096); 
  360.  
  361. insert into t_longcol_53(longcol17) select repeat('a',8192); 
  362.  
  363. insert into t_longcol_54(longcol18,longcol19) select 
  364. repeat('a',16284), 
  365. repeat('a',20380); 
  366.  
  367. insert into t_longcol_55(longcol20) select repeat('a',5977); 
  368.  
  369. set @i = @i + 1; 
  370. end while; 
  371. end


上述各个测试表都写入5000行记录后,再来对比下其表空间文件大小,以及重整表空间后的大小,观察碎片率。详细对比见下:

提高MySQL中InnoDB表BLOB列的存储效率的教程

最后一种分表方式中,5个子表的表空间文件大小总和是 40960 + 40960 + 98304 + 286720 + 40960 = 507904 字节。

可以看到,这种方式的总大小和原始表大小差距最小,其他几种存储方式都比这个来的大。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表