MySQL的数据压缩性能对比

日期: 2011-03-23 作者:淘宝数据平台与产品部官方博客 来源:TechTarget中国 英文

  数据魔方需要的数据,一旦写入就很少或者根本不会更新。这种数据非常适合压缩以降低磁盘占用。MySQL本身提供了两种压缩方式——archive引擎以及针对MyISAM引擎的myisampack方式。今天对这两种方式分别进行了测试,对比了二者在磁盘占用以及查询性能方面各自的优劣。

  1. 测试环境:

  软硬件

  一台 64位 2.6.18-92 内核Linux开发机,4G内存,4个2800Mhz Dual-Core AMD Opteron(tm) Processor 2220 CPU。

  MySQL放在一块7200转SAT硬盘,未做raid;

  MySQL未做任何优化,关闭了query cache,目的在于避免query cache对测试结果造成干扰。

  表结构

  2424753条记录,生产环境某一个分片的实际数据;

  分别建立了(partition_by1,idx_rank) 和 (partition_by1,chg_idx)的联合索引,其中partition_by1为32长度的varchar类型,用于检索;其余两个字段均为浮点数,多用于排序;

  autokid作为子增列,充当PRIMARY KEY,仅作为数据装载时原子性保证用,无实际意义。

  2. 测试目的:

  •   压缩空间对比

  压缩率越大,占用的磁盘空间越小,直接降低数据的存储成本;

  •   查询性能对比

  压缩后查询性能不应该有显著降低。Archive是不支持索引的,因此性能降低是必然的,那么我们也应该心里有个谱,到底降低了多少,能不能接受。

  3. 测试工具:

  mysqlslap

  官方的工具当然是不二之选。关于mysqlslap的介绍请参考 官方文档。

  测试query

  截取生产环境访问topranks_v3表的实际SQL共9973条,从中抽取访问量较大的7条,并发50,重复执行10次。命令如下:

  ./mysqlslap –defaults-file=../etc/my.cnf -u**** -p**** -c50 -i10 -q ../t.sql –debug-info

  4.测试结论

  比较项磁盘空间耗时(秒)CPU IdleLOAD并发

  基准表(MyISAM)4039560042.308301550

  ARCHIVE75630745>3007541

  PACK993021092.596302250

  根据上面的表格给出的测试数据,我们简单得出以下结论:

  针对测试表,Archive表占用空间约为之前的18.7%,myisampack后空间占用约为之前的24.6%;二者相差不多,单纯从空间利用情况来看,我们似乎需要选择archive表;

  我们再看查询性能,与基准表进行对比。无论在总耗时还是系统负载方面,50并发下的pack表查询性能与基准表相当;而archive表在单并发情况下耗时超过了5分钟(实在等不了了,kill之)!

  那么,我们似乎可以得出结论,针对需要在线查询的表,ARCHIVE引擎基本上可以不考虑了。

  为什么这个测试过程中ARCHIVE引擎如此地慢呢?

  我们知道,mysql提供archive这种存储引擎是为了降低磁盘开销,但还有一个前提,那就是被归档的数据不需要或者很少被在线查询,偶尔的查询慢一些也是没关系的。鉴于上述原因,archive表是不允许建立自增列之外的索引的。

  有了这个共识,我们拿一条测试SQL来分析一下不用索引前后的查询性能差别为什么这么大。在我们的测试SQL中有这么一条:

  SELECT c1,c2,…,cn FROM mysqlslap.rpt_topranks_v3

  WHERE … AND partition_by1 = ‘50008090’

  ORDER BY added_quantity3 DESC

  LIMIT 500

  我们前边说过,测试的这个表在partition_by1这个字段上建立了索引,那么,我们初步判断在基准表和myisampack表上,这个查询应该用到了partition_by1的索引;EXPLAIN一下:

  mysql> EXPLAIN

  -> SELECT … FROM mysqlslap.rpt_topranks_v3

  -> WHERE … AND partition_by1 = ‘50008090’

  -> ORDER BY added_quantity3 DESC

  -> LIMIT 500G

  *************************** 1. row ***************************

  id: 1

  select_type: SIMPLE

  TABLE: rpt_topranks_v3

  type: ref

  possible_keys: idx_toprank_pid,idx_toprank_chg

  KEY: idx_toprank_pid

  key_len: 99

  ref: const

  rows: 2477

  Extra: USING WHERE; USING filesort

  1 row IN SET (0.00 sec)

  正如我们所料,这个查询用到了建立在partition_by1这个字段上的索引,匹配的目标行数为2477,然后还有一个在added_quantity3字段上的排序。由于added_quantity3没有索引,所以用到了filesort。

  我们再看一下这条SQL在归档表上的EXPLAIN结果:

  mysql> EXPLAIN

  -> SELECT … FROM mysqlslap.rpt_topranks_v3_archive

  -> WHERE … AND partition_by1 = ‘50008090’

  -> ORDER BY added_quantity3 DESC

  -> LIMIT 500G

  *************************** 1. row ***************************

  id: 1

  select_type: SIMPLE

  TABLE: rpt_topranks_v3_archive

  type: ALL

  possible_keys: NULL

  KEY: NULL

  key_len: NULL

  ref: NULL

  rows: 2424753

  Extra: USING WHERE; USING filesort

  1 row IN SET (0.00 sec)

  EXPLAIN说:“我没有索引可用,所以只能全表扫描2424753行记录,然后再来个filesort。”你要追求性能,那显然是委屈MySQL了。

我们一直都在努力坚持原创.......请不要一声不吭,就悄悄拿走。

我原创,你原创,我们的内容世界才会更加精彩!

【所有原创内容版权均属TechTarget,欢迎大家转发分享。但未经授权,严禁任何媒体(平面媒体、网络媒体、自媒体等)以及微信公众号复制、转载、摘编或以其他方式进行使用。】

微信公众号

TechTarget微信公众号二维码

TechTarget

官方微博

TechTarget中国官方微博二维码

TechTarget中国

电子邮件地址不会被公开。 必填项已用*标注

敬请读者发表评论,本站保留删除与本文无关和不雅评论的权力。

相关推荐