innodb使用大字段text,blob的一些优化建议

最近看到一些老应用,在表结构的设计上使用了text或者blob的字段;其中一个应用,对blob字段的依赖非常的严重,查询和更新的频率也是非常的高,单表的存储空间已经达到了近100G,这个时候,应用其实已经被数据库绑死了,任何应用或者查询逻辑的变更几乎成为不可能;

为了清楚大字段对性能的影响,我们必须要知道innodb存储引擎在底层对行的处理方式:

知识点一:在5.1中,innodb存储引擎的默认的行格式为compact(redundant为兼容以前的版本),对于blob,text,varchar(8099)这样的大字段,innodb只会存放前768字节在数据页中,而剩余的数据则会存储在溢出段中(发生溢出情况的时候适用);

知识点二:innodb的块大小默认为16kb,由于innodb存储引擎表为索引组织表,树底层的叶子节点为一双向链表,因此每个页中至少应该有两行记录,这就决定了innodb在存储一行数据的时候不能够超过8k(8098字节);

知识点三:使用了blob数据类型,是不是一定就会存放在溢出段中?通常我们认为blob,clob这类的大对象的存储会把数据存放在数据页之外,其实不然,关键点还是要看一个page中到底能否存放两行数据,blob可以完全存放在数据页中(单行长度没有超过8098字节),而varchar类型的也有可能存放在溢出页中(单行长度超过8098字节,前768字节存放在数据页中);

知识点四:5.1中的innodb_plugin引入了新的文件格式:barracuda(将compact和redundant合称为antelope),该文件格式拥有新的两种行格式:compressed和dynamic,两种格式对blob字段采用完全溢出的方式,数据页中只存放20字节,其余的都存放在溢出段中:

知识点五:mysql在操作数据的时候,以page为单位,不管是更新,插入,删除一行数据,都需要将那行数据所在的page读到内存中,然后在进行操作,这样就存在一个命中率的问题,如果一个page中能够相对的存放足够多的行,那么命中率就会相对高一些,性能就会有提升;

有了上面的知识点,我们一起看看该应用的特点,表结构:

CREATE TABLE `xx_msg` (
  `col_user` VARCHAR(64)  NOT NULL,
  `col_smallint` SMALLINT(6) NOT NULL,
  `col_lob` longblob,
  `gmt_create` datetime DEFAULT NULL,
  `gmt_modified` datetime DEFAULT NULL,
  PRIMARY KEY (`xxx`)
) ENGINE=InnoDB DEFAULT CHARSET=gbk

col_lob为blob字段,用于存放该用户的所有的消息,其平均长度在2.4kb左右,该表中其他剩余的字段则是非常的小,大致在60字节左右

SELECT avg(LENGTH(col_clob)) FROM (SELECT * fromxxx_msg LIMIT 30000)a;
|         2473.8472 |

该表的应用场景包括:

1) select col_user ,col_smallint,DATE_FORMAT(gmt_modified,’%Y-%m-%d’) from xx_msg;

2) update xx_msg set gmt_modified=’2012-03-31 23:16:30′,col_smallint=1,col_lob=’xxx’ where col_user=’xxx’;

3) select col_smallint from xx_msg where user=’xxx’;

可以看到由于单行的平均长度(2.5k)还远小于一个innodb page的size(16k)(当然也有存在超过8k的行),也就是知识点三中提到的,blob并不会存放到溢出段中,而是存放到数据段中去,innodb能够将一行的所有列(包括longlob)存储在数据页中:

在知识点五中,mysql的io以page为单位,因此不必要的数据(大字段)也会随着需要操作的数据一同被读取到内存中来,这样带来的问题由于大字段会占用较大的内存(相比其他小字段),使得内存利用率较差,造成更多的随机读取。

从上面的分析来看,我们已经看到性能的瓶颈在于由于大字段存放在数据页中,造成了内存利用较差,带来过多的随机读,那怎么来优化掉这个大字段的影响:

一.压缩:

在知识点四中,innodb提供了barracuda文件格式,将大字段完全存放在溢出段中,数据段中只存放20个字节,这样就大大的减小了数据页的空间占用,使得一个数据页能够存放更多的数据行,也就提高了内存的命中率(对于本实例,大多数行的长度并没有超过8k,所以优化的幅度有限);如果对溢出段的数据进行压缩,那么在空间使用上也会大大的降低,具体的的压缩比率可以设置key_blok_size来实现。

二.拆分:

将主表拆分为一对一的两个关联表:

CREATE TABLE `xx_msg` (
  `col_user` VARCHAR(64)  NOT NULL,
  `col_smallint` SMALLINT(6) NOT NULL,
  `gmt_create` datetime DEFAULT NULL,
  `gmt_modified` datetime DEFAULT NULL,
  PRIMARY KEY (`xxx`)
) ENGINE=InnoDB DEFAULT CHARSET=gbk;
 
CREATE TABLE `xx_msg_lob` (
  `col_user` VARCHAR(64)  NOT NULL,
  `col_lob` longblob,
   PRIMARY KEY (`xxx`)
) ENGINE=InnoDB DEFAULT CHARSET=gbk

xx_msg表由于将大字段单独放到另外一张表后,单行长度变的非常的小,page的行密度相比原来的表大很多,这样就能够缓存足够多的行,表上的多个select由于buffer pool的高命中率而受益;应用程序需要额外维护的是一张大字段的子表;

三.覆盖索引:

在上面的两个查询当中,都是查询表中的小字段,由于老的方案需要全表或者根据主键来定位表中的数据,但是还是以page为单位进行操作,blob字段存在还是会导致buffer pool命中率的下降,如果通过覆盖索引来优化上面的两个查询,索引和原表结构分开,从访问密度较小的数据页改为访问密度很大的索引页,随机io转换为顺序io,同时内存命中率大大提升;额外的开销为数据库多维护一个索引的代价;

alter table xx_msg add index ind_msg(col_user ,col_smallint,gmt_modified);

对于查询一,原来的执行计划为走全表扫描,现在通过全索引扫描来完成查询;

对于查询二,原来的执行计划为走主键PK来定位数据,现在该走覆盖索引ind_msg完成查询;

注意上面的两个查询为了稳固执行计划,需要在sql执行中加入hint提示符来强制sql通过索引来完成查询;

总结:上面三种思路来优化大字段,其核心思想还是让单个page能够存放足够多的行,不断的提示内存的命中率,尽管方法不同,但条条大路通罗马,从数据库底层存储的原理出发,能够更深刻的优化数据库,扬长避短,达到意想不到的效果。

ref:《innodb 技术内幕》

ref:MySQL Blob Compression performance benefits

ref:   Data compression in InnoDB for text and blob fields

ref:Handling long texts/blobs in InnoDB – 1 to 1 relationship, covering index

时间: 2024-11-03 20:47:11

innodb使用大字段text,blob的一些优化建议的相关文章

InnoDB行格式对text/blob大变长字段的影响

最近在排查现网Text与Blob类型,发现有不少,在<高性能MySQL(第3版)>看到对这两种变长数据类型的处理会涉及到在磁盘上创建临时表,性能开销比较大.于是把影响blob型数据存储方式了解了一下:row_format. 1. InnoDB的Antelop与Barracuda文件格式 Innodb存储引擎保存记录,是以行的形式存放的(与之对应的是像Google BigTable这种列数据库).在InnoDB 1.0.x版本之前,InnoDB 存储引擎提供了 Compact 和 Redunda

使用大数据做出更明智的业务决策

使用大数据做出更明智的业务决策 事实证明,与技术解决方案一样,要想通过大数据获得成功也需要技巧. NewVantage Partners在去年夏季与来自50多家大型公司的高管(主要是首席数据官.首席信息官.首席技术官.首席分析官.首席信息架构师).业务主管和高级程序员进行了研讨.在这些大型公司中,多数公司的员工数量都超过了30000人.在NewVantage Partners公司的调查中,有一半的受访者为来自金融服务公司的高管,另外一半的受访者为来自保险.政府机构以及其他行业的公司高管. New

java 如何保存、读取数据库字段为blob类型的值

问题描述 java 如何保存.读取数据库字段为blob类型的值 java 如何保存.读取javaBean中定义String类型,oracle数据库字段为blob类型的值 这是我的业务逻辑代码 try { String encoding = "GBK"; File file = new File("E:workspaceNeuSoft omcat7.0.40logslocalhost.2015-12-07.log"); if (file.isFile() &&

如何更好的使用大数据?

大数据(Big data)通常用来形容一个公司创造的大量非结构化和半结构化数据.大数据在互联网行业指的是这样一种现象:互联网公司在日常运营中生成.累积的用户网络行为数据. 大数据的特征:数据量大(Volume):类型繁多(Variety):价值密度低(Value):速度快时效高(Velocity). 大家看过的例子:啤酒与尿布.沃尔玛的员工发现啤酒和尿布经常放在一个购物篮里面,调查发现爸爸经常在买尿布的时候顺带买啤酒,所以沃尔玛把啤酒和尿布放在同一区域.这个例子表明:两种商品之间是有相互联系的,

使用大数据,就像在沙子里淘金

美国约翰·霍普金斯大学博士.腾讯前副总裁.Google科学家.著名自然语言处理和搜索专家吴军,日前在复旦大学管理学院的一次公开演讲中,对当下大热的人工智能和大数据的发展,做出了自己的分析和展望. 怎样的大数据才意味着突破 在过去几年,我们这个世界上的数据的增长速度,相当于之前5年.10年的50倍. 大数据为什么在这个点上爆发?主要原因是,摩尔定律使得存储的数据量空前扩张.与此同时,类似RFID那样的传感器技术也得到了质的提升.于是,就出现了这样的例子-- 当某著名服饰品牌把RFID的芯片放在衣服

使用大数据洞察 更贴近消费者

在互联网发展的下一个阶段,企业需要思考和工作的方式将会很不同,这个阶段,到处都充斥着无数新的机遇,无论是车联网还是智能家居,物联网将会对我们生活的各个方面产生深远的影响. 随着物联网时代的到来,消费者会购入越来越多的智能设备来提升生活的品质,这是一个令人难以置信的机遇,作为企业,也必须去学会顺应物联网时代的大潮,并不断的提升企业运营能力和转变营销方式.这就需要企业去更好的去理解物联网对企业品牌意味着什么?如何分析和使用大数据,与技术支撑方的密切合作,以及提出更好的企业创新方案?所以,作为物联网企

英国使用大数据政府每年可节省330亿英镑

智囊团Policy http://www.aliyun.com/zixun/aggregation/14454.html">Exchange称,英国政府通过高效使用公共大数据每年可节省330亿英镑.这个数字相当于英国每人每年节省500英镑. Policy Exchange认为,应该在白厅搭建专业级别的"Data Force",这样就可以开始评测具体所节省资金的金额.这样也可以有效防止诸如逃税漏税.福利欺诈等行为. Policy Exchange提交了一份名为"

汽车制造厂商使用大数据的5个创新思路

随着如今迅速发展的技术,现代汽车已经成为带有轮子.安全气囊与乘客空间的计算机.运用在汽车上的创新可以为司机规划安全路线.播放卫星广播.连接手机免提功能.使汽车保持在车道内行驶.并通过距离感应器和自动驾驶避免交通事故的发生.所有的这些功能增强和改进都归功于先进的软件技术和大数据分析. 什么是大数据? 大数据是对非常大量的数据进行收集和分析的产物,这些信息数据可以通过计算机进行分类排序,从而揭示某种趋势.模式或关联.当涉及到人类的行为,以及人类与某个产品或某种服务之间的交互行为,大数据技术将尤为实用

创业公司如何使用大数据获取成功?

导语:在星河互联举办的"星河互联2.0--一站式互联网创业服务开放平台发布会"上,<大数据时代>作者.被<经济学人>定义为大数据领域最受人尊敬的权威发言人之一的维克托 迈尔-舍恩伯格发表了"洞见未来"的主题演讲.维克托·迈尔·舍恩伯格著作的<大数据时代>被称为国外大数据研究的先河之作,维克托被誉为"大数据商业应用第一人",在牛津大学.哈佛大学.耶鲁大学.新加坡国立大学等多个互联网研究重镇任教的经历,早在2010