文档章节

mysql的varchar大字段性能研究

中小宇
 中小宇
发布于 06/14 11:37
字数 956
阅读 11
收藏 0

我们知道,innodb的一个页是16K(16*1024=16384字节),如果一条记录占的字节数大于16K,意味着一个页无法装下一条记录,这种情况下mysql是如何处理的呢?

  在回答这个问题之前我们先来做一个实验:

  我们创建了两张表,分别是T1和T2,T1和T2唯一的区别是在于b字段一个是varchar(8094),另一个是varchar(8095),然后我们有一个T1_test.sql文件,该文件包含有10W行“insert into T1 values(1,repeat('a',8094));”条sql语句,我们导入到表里花费了4分24秒。

  接着我们把T2_test.sql导入T2表中(T2.test.sql同样也包含了10W行类似的sql语句),花费了9分58秒!

  我们再来看这两个表文件的空间占用情况(本实例开启了innodb_file_per_talbe):

  可以看到T1表占用804M,T2表占用空间1.9G,空间及时间差异均超过2倍。

  为什么相差一个字符时间和空间相差会如此巨大呢?下面我们一起剖析下。

  在innodb存储引擎里,将一条记录中的某些数据存储在真正的数据页面之外称之为行溢出数据,一般认为blob、text这类的大对像列的存储会把数据存放在数据页面之外。但从上述我们的实验看出,除了blob、text这类大对像列以外,varchar类型似乎也会采用行溢出的方法来存储数据。

  Innodb存储引擎表是索引组织的,即B+树的结构,因此每个页中至少应该有两个行记录(否则失去了B+树的意义,变成链表了),如果页中只能存放下一条记录,那么InnoDB存储引擎会自动将行数据存放到溢出页中,以使每个页最少能存放两个行记录或以上。

  下面借助姜承尧先生写的py_innodb_page_info工具来证实T2发生了行溢出(点击这里可取得该工具源代码

  为了更清晰的分析原因,下面我们分别创建T1_1和T2_1表,其b字段也相差1字符,然后分别往这两个表插入一条记录,如下图所示:

  

  此时我们通过py_innodb_page_info工具分析T1_1表的情况

上图说明表T1_1只包含了一个B-tree,我们再看看T2_1的情况:

   我们看到T2_1表比T1_1表多了一页“Uncompressed BLOB Page”的页,这也充分说明了插到T2_1个的记录分了两页存储,其中一页是BLOB页。

  在上述的实验中,我们故意采取了两个字段,一个字段是4字节的int,另一个字段是varchar(8094),两者加起来即8098,也就说,当一个表的字段总大小数大于8098时,插入一条记录即会分裂成两页存储,故无论时间还是空间方面都大打折扣,有兴趣的读者可尝试下用一个或多个字段大小总和<=8098及>8098来做对比。

  大家在实验过程中要注意一点的是,当varchar小于255时,会额外用1个字节来记录该记录的实际长度,当varchar大于255时会用2个字节,因为时使用多个变长字段实验时,要注意其总大小要加上该空间。例如:“create table A1(a int, b varchar(2000), c varchar(3000), d varchar(3090));”那么此时的临界值就是4+2000+3000+3090=8090,因为相对于我们上述的实验,A1这个表多了两个大于255的varchar字段,因此需要额外的2+2=4字节来记录变长字段。

本文转载自:https://blog.csdn.net/mysqltop/article/details/21135239

共有 人打赏支持
中小宇
粉丝 6
博文 41
码字总数 20933
作品 0
福州
高级程序员
私信 提问
mysql的varchar大字段性能研究

我们知道,innodb的一个页是16K(16*1024=16384字节),如果一条记录占的字节数大于16K,意味着一个页无法装下一条记录,这种情况下mysql是如何处理的呢?   在回答这个问题之前我们先来做...

李_正
2016/04/15
494
0
MySQL字符数据类型char与varchar的区别

数据类型差不多是接触mysql一开始就了解的内容,最近遇到几个现象如varchar自动转mediumtext,blob存储性能的问题,不得不回头明确一下关于MySQL常用数据类型的选择。 mysql手册这里 已经讲的...

seanlook
08/27
0
0
infobright实战

之前的简介与架构分析之后,我做了一些实践,验证 infobright用于大量数据存储与查询的可行性。 我是从这里下载的infobright开源版本ICE3.1(据说刚出的ICE3.2查询速度更快)。用DEB包在ubu...

小编辑
2010/02/03
3.3K
0
MySQL索引类型详解,让MySQL高效运行起来

索引是快速搜索的关键。MySQL索引的建立对于MySQL的高效运行是很重要的。下面介绍几种常见的MySQL索引类型。 在数据库表中,对字段建立索引可以大大提高查询速度。假如我们创建了一个 mytabl...

Junn
2013/07/24
0
0
与技术谈一场永不分手的恋爱

找到一份合适的工作,就像在工作的八小时之内有了一个心仪的恋人。 老张我呢,原来在上学那会儿,不是特别爱学习,本人长得呢也特别帅(现在做了技术可惜了哈哈!)所以特招漂亮女孩的喜欢,...

superZS
2017/07/21
0
0

没有更多内容

加载失败,请刷新页面

加载更多

CentOS 安装PHP5和PHP7

安装PHP5 下载解压二进制包 [root@test-a src]# cd /usr/local/src/[root@test-a src]# wget http://cn2.php.net/distributions/php-5.6.32.tar.bz2[root@test-a src]# tar jxvf php-5.6......

野雪球
今天
4
0
windows上类似dnsmasq的软件Dual DHCP DNS Server

官网地址:http://dhcp-dns-server.sourceforge.net/官网定向的下载地址:https://sourceforge.net/projects/dhcp-dns-server/files/ 设置参考地址:http://blog.51cto.com/zhukeqiang/18264......

xueyuse0012
今天
3
0
LinkedHashMap源码解析

前言 HashMap中的元素时无序的,也就是说遍历HashMap的时候,顺序和放入的顺序是不一样的。 如果需要有序的Map,就可以采用LinkedHashMap. LinkedHashMap通过维护一个包含所有元素的双向链表,...

grace_233
今天
3
0
初识flask

文档 0.10.1版本 http://www.pythondoc.com/flask/index.html 1.0.2版本 https://dormousehole.readthedocs.io/en/latest/ 安装flask $ pip3 install flaskCollecting flask Downloading......

yimingkeji
昨天
5
0
Akka系统《sixteen》译

Actor是一个封装状态(state)和行为(behavior)的对象,它们只通过交换消息通信(放入收件人邮箱的邮件)。从某种意义上说,Actor是最严格的面向对象编程形式,但它更适合将他们视为人:在与Act...

woshixin
昨天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部