技术开发 频道

四款主流列式数据库横评

  2. 从数据库内部抽取部分数据到其他表

  各种数据库从库内转移数据的能力各不相同,Infobright,SybaseIQ,Oracle均支持insert into 表1 select * from 表2这种方式。

  Infobright 虽然支持这种方式,但它的内部操作过程,是先把压缩数据解压缩到cache目录,然后从cache目录读取数据插入压缩表,当数据量较大时,这种做法不但占用了大量磁盘空间,转换时间很长,而且还很容易失败,不如将数据先导出为文本,再用load data加载效率高,因此实用性有限。

  InfiniDB不支持子查询插入,只能通过文本或操作系统管道导出和导入,这点也有待加强。那么只剩下Sybase和Oracle可以一较高下了。

  我们从hu表取出ID第一位为'1'的记录保存到hu1表,Oracle占用的时间是56.99秒,上篇文章SybaseIQ的用时是271.953秒。但考虑到SybaseIQ自动创建索引的消耗,这个时间差是可以接受的。

  Oracle的命令行:

SQL> create table hu1 compress parallel(degree 8)
partition by range(id)
(partition p11 values less than ('12'),
partition p12 values less than ('13'),
partition p13 values less than ('14'),
partition p14 values less than ('15'),
partition p15 values less than ('16')
)
as select /*+parallel (hu,8)*/ * from hu where id
< '2';
表已创建。

已用时间:  00: 01: 13.04
SQL
> select count(*) from hu1;

  COUNT(*)
----------
  41533005

已用时间:  00: 00: 00.51
 

  (二) 数据压缩

  Sybase IQ采用sp_iqtablesize('用户名.表名')查看各个表占用的空间大小。我们将Kbytes的数据换算成GB。

  Oracle采用查询USER_SEGMENT数据字典的bytes列的总和查看。同样换算成GB。

  Infobright采用du -sh 目录名 查看数据存储目录下的物理文件大小。或者查询information_schema系统库的tables表,这2种方法得到的结果是相近的。

mysql> SELECT TABLE_SCHEMA,TABLE_NAME,DATA_LENGTH+INDEX_LENGTH,TABLE_ROWS FROM TABLES WHERE TABLE_SCHEMA in ('tpch2')order by 1,2;
+--------------+------------+--------------------------+------------+
| TABLE_SCHEMA | TABLE_NAME | DATA_LENGTH+INDEX_LENGTH | TABLE_ROWS |
+--------------+------------+--------------------------+------------+
| tpch2        | CUSTOMER   |                 80638414 |    1500000 |
| tpch2        | LINEITEM   |               1284138449 |   59986052 |
| tpch2        | NATION     |                     1830 |         25 |
| tpch2        | ORDERS     |                314605383 |   15000000 |
| tpch2        | PART       |                 31483651 |    2000000 |
| tpch2        | PARTSUPP   |                235571312 |    8000000 |
| tpch2        | REGION     |                      907 |          5 |
| tpch2        | SUPPLIER   |                  5179217 |     100000 |
+--------------+------------+--------------------------+------------+

[root@redflag11012601 infbhtdata]# du -s tpch2/*bht
78964   tpch2/CUSTOMER.bht
1255568 tpch2/LINEITEM.bht
80      tpch2/NATION.bht
307708  tpch2/ORDERS.bht
30932   tpch2/PART.bht
230384  tpch2/PARTSUPP.bht
64      tpch2/REGION.bht
5192    tpch2/SUPPLIER.bht

  InfiniDB的information_schema系统库的信息不正确,也没有提供其它的函数或过程,只能从磁盘空间粗略估算,而且它的命名规律不是人能读懂的格式,只能从导入前后的空间差计算,这点不太方便,有待改进。Calpont的技术支持给我提供了一套脚本,在Linux操作系统下运行,可以列出数据库、表、列占用的存储空间,本文的数据就用此脚本的结果。

[root@redflag11012601 scripts]# ./databaseSizeReport.sh
ssb:
4.48282 GB
tpch:
8.18472 GB
rk:
30.4541 GB
rki:
17.3675 GB

  为了给出和专用压缩工具压缩绿的比较,专门引入了gzip格式的默认压缩文件大小。

7

  我们将原始csv文件的大小除以各种数据库压缩后的数据大小,得到的倍数作为它们的压缩率,得到下面的表格:

7

  由此得到的统计图如下:

7
▲各种数据库压缩率统计图(单位:GB)

  从上图我们可以直观地看出,对于每种数据集Infobright压缩后的空间是最小的,对于整数类型压缩率尤其高,实际上它比gzip的压缩率更高,一般而言SybaseIQ次之,InfiniDB较差,但也不一定,压缩效果跟数据的分布关系密切,比如对于用户实际的rk数据集,SybaseIQ压缩率反而不如InfiniDB。大部分列存储的压缩率和行存储的Oracle相比差别不大,当然,在存储日益廉价的当今,数据占用空间不是主要的问题,更主要的是查询效率。

2
相关文章