1. Mysql 性能分析之临时表
1 临时表与磁盘临时表 ............................................................................................................... 1
2 磁盘临时表的产生 ................................................................................................................... 1
3 临时表状态监控 ....................................................................................................................... 2
3.1 主要指标 ....................................................................................................................... 2
3.2 监控方法 ....................................................................................................................... 3
4 案例分析 .................................................................................................................................. 4
.
1 临时表与磁盘临时表
临时文件大家都不陌生,就是为了各种不同的目的,产生的中间文件。使用完毕后会被及时
s
的回收和清理。临时表也是如此,它是 mysql 在进行一些内部操作的时候生成的数据库表。
这些操作主要包括,group by, distinct,一些 order by 查询语句,UNION,一些 from 语句中
的子查询(derived tables)等。例如:
使用了 order by 子句和一个不同的 group by 子句,或者 order by(或 group by)包含了
lu
ha
JOIN queue 上非第一个表中的列,临时表将被创建。
使用了 SQL_SMALL_RESULT 选项,mysql 会使用 in‐memory 临时表
DISTINCT 和 order by 一起使用可能会用到临时表
p
可以使用 EXPLAIN 来分析查询语句,看看是否会用到临时表。EXPLAIN 输出中的 EXTRA 列会
ce
指明是否“Using temporary” 。
事实上,大多数用户都不会去关注临时表的产生、使用与消亡的过程,因为它对用户是透明
的。但是对于数据库管理员或者其他关心性能的人员而言,临时表就不得不引起注意,因为
bu
如果设置不当或者是程序使用不当, 可能会产生大量的磁盘临时表, 对系统性能产生很大的
影响。
什么是磁盘临时表呢?
除了会直接产生磁盘临时表外, 大量磁盘临时表是由内存临时表转化来的。 临时表是存在于
内存中,由 MEMORY 引擎进行处理,速度较快。而磁盘临时表则是在磁盘上创建、使用、
销毁的。由于磁盘是慢速访问设备,因此,磁盘临时表的操作效率要比临时表的操作差了几
个数量级,具有较差的性能。因此,我们需要尽量避免磁盘临时表的产生。
2 磁盘临时表的产生
在使用中,有些时候是不能使用 MEMORY 临时表的,而不得不使用 MyISAM 引擎来处理临
时表:
列中含有 BLOB 或 TEXT 字段
如果查询中包含 BLOB 或者 TEXT 列,临时表将直接被生成为 MyISAM 表,因为这种类
Author: beiyu95 msn:beiyu95@hotmail.com
2. 型的列不能存储在 Memory 表中。
值得注意的是,一些设计上的问题可能会导致内存临时表的大小比想象中的大得多,
Memory 表总是使用固定长度的列,因此,假如 varchar(255)类型的列中只存储了 y,n 这
样的值,而在内存中占有的大小依然是 255,如果是 utf8 编码,就是 255*3 。这也是
为什么要避免使用不必要的长度来存储内容的重要原因。
ORDER BY 或 DISTINCT 中出现了大于 512bytes 的列
在使用 UNION(ALL)的情况下,SELECT 子句中出现了大于 512byte 的列
另外,当创建的 MEMORY 临时表过大时,将被转换为 MyISAM 表,并且存储在磁盘上。系
统参数 max_heap_table_size 决定了 MEMORY 表大小的上限,适用于所有的内存表,包括使
用 CREATE TABLE 创建的表。但是,对于内部临时 MEMORY 表而言,其大小还有受限于
tmp_table_size。也就是说, 内存临时表的上限实际上是 max_heap_table_size 和 tmp_table_size
二者中的最小值。当 MEMORY 表大小超过最大值时,将被自动转换为存储在磁盘上的磁盘
临时表,使用 MyISAM 引擎进行处理。
从 mysql 的临时文件夹中可以查看是否会产生磁盘临时表,磁盘临时表是以#开头的文件。
下面是每秒一次产生的一段查看快照:
s
lu
p ha
ce
bu
3 临时表状态监控
3.1 主要指标
在性能测试的过程中,临时磁盘表的大量产生会造成较多的 IO,使系统性能大幅下降。和
磁盘临时表相关的主要参数有:
MAX_HEAP_TABLE_SIZE
MEMORY 表大小的最大值,通过这个值来计算 MEMORY 表的最大行数
MAX_TMP_TABLES
Author: beiyu95 msn:beiyu95@hotmail.com
3. 一个客户端同时打开的临时表个数限制
TMP_TABLE_SIZE
临时表的最大值。超过了这个值,内存中的 MEMORY 表将被自动转换为磁盘上的
MyISAM 表。
CREATED_TMP_DISK_TABLES
创建的磁盘临时表的个数。
CREATED_TMP_TABLES
创建的内存临时表的个数
下面是一次性能测试过程中,对临时表性能监控的快照。
在性能测试的过程中是通过 100*(磁盘临时表个数/(磁盘临时表个数+内存临时表个数)),
也就是磁盘临时表占临时表的比例来衡量这个指标的健康程度的。
3.2 监控方法
在测试过程中,可以通过 show status 命令的输出来查看临时表的状态变量,可以通过 show
s
variables 来查看系统参数的设置。
如果想观察一段时间内指标的变化,可以借助脚本或者第三方工具来进行查看。Mysql
manager 就是一个不错的开源工具,它提供了丰富的管理、监控功能。通过它我们可以方便
的查看状态变量、系统参数,还可以进行自定义图表,通过定义自己的公式来添加关心的指
lu
ha
标。
p
ce
bu
官方下载地址:http://dev.mysql.com/downloads/gui‐tools/5.0.html
Author: beiyu95 msn:beiyu95@hotmail.com
4. 4 案例分析
在维护模块客户报表批量下载功能的测试中,发现 max_heap_table_size 的值为 32M,而
tmp_table_size 的值为 512M。有大量的磁盘临时表产生。
s
lu
ha
根 据 前 面 的 分 析 , 可 能 会 是 由 于 max_heap_table_size 参 数 过 小 导 致 。 于 是 将
max_heap_table_size 的值调整为 512M。挑选同一个任务,进行测试,同一个任务调整前后
磁盘临时表的比率分别在 90%和 10%。 说明参数的调整大大减少了磁盘临时表的产生, 提高
p
了操作效率。
ce
优化前后对比如下:
bu
通过提高该参数的值,可以解决大量磁盘临时表的问题,但是应当注意的有两点:
1. 参数设置只是一部分, 相当一部分磁盘表的产生是由与 SQL 和数据库的不合理设计造成
的,比如含有 TEXT 字段,这也是我们进行优化和问题分析的重点。
2. 不能盲目调大临时表的参数,因为内存是有限的,需要从全局来考虑。对参数的调整要
进行系统的测试,以获得整体性能的提升。
Author: beiyu95 msn:beiyu95@hotmail.com
5. s
lu
ha
p
ce
bu
Author: beiyu95 msn:beiyu95@hotmail.com