« SQLULDR2集成GZIP压缩 »
Tools » http://www.anysql.net/tools/sqluldr2_compress.html 2009-04-16数据压缩可以节约很多的空间, GZIP是一个比较优秀的算法, 在空间和压缩速度之间有一个良好的平衡, 很多软件只内嵌的压缩算法都是GZIP算法, 例如rsync的压缩传模式. 花了几天时间研究了一下开源压缩模块(zlib)的编程接口后, 将它集成到了文本导出工具(sqluldr2)中, 可以直接生成压缩后的文件. 只要输出文件名最后以".gz"结尾, 就会自动启用压缩模式, 不需要用专门的命令行选项.
D:\OracleClient>sqluldr2zip parfile=testpar.txt file=a.txt.gz
0 rows exported at 2009-04-16 17:48:09
50 rows exported at 2009-04-16 17:48:09
output file a.txt.gz closed at 50 rows.
先用小数据量测试一下功能, 用Winzip或gunzip可以成功解压生成的压缩文件.
D:\OracleClient>dir a.txt.*
2009-04-16 09:48 1,589 a.txt
2009-04-16 17:48 704 a.txt.gz
晚上再用前段时间测试性能的数据测试一下压缩方式的效率, 测试数据会稍后贴在回复中. 有压缩模式后, 可以更方便地使用SQLULDR2来归档静态的历史数据. 如果在Linux或Unix下也可以用重定向来实现这个功能.
sqluldr2 ... file=- | gzip > a.txt.gz
个人比较喜欢集成起来使用.


我的测试表中全是重复的记录, 因此压缩比很高, 速度居然没有因为压缩而受到影响.
D:\>sqluldr2zip parfile=testpar.txt key=sqluldr.key
0 rows exported at 2009-04-16 19:04:13
1000000 rows exported at 2009-04-16 19:04:19
2000000 rows exported at 2009-04-16 19:04:25
3000000 rows exported at 2009-04-16 19:04:32
3670086 rows exported at 2009-04-16 19:04:37
output file uldrdata.txt closed at 3670086 rows.
D:\>sqluldr2zip parfile=testpar.txt key=sqluldr.key file=uldrdata.txt.gz
0 rows exported at 2009-04-16 19:04:45
1000000 rows exported at 2009-04-16 19:04:51
2000000 rows exported at 2009-04-16 19:04:58
3000000 rows exported at 2009-04-16 19:05:04
3670086 rows exported at 2009-04-16 19:05:09
output file uldrdata.txt.gz closed at 3670086 rows.
D:\>dir uldr*.*
2009-04-16 19:04 198,971,091 uldrdata.txt
2009-04-16 19:05 1,270,269 uldrdata.txt.gz
现在cpu都是多核,下一步该研究并行了
并行的问题,以前考虑过,没有好的思路.
用c语言找回被wget -c误覆盖的文件
#include
int main2(int argc, char *argv[])
{char buf[50000];
FILE *fp=fopen(“C:\\0\\cls\\a.zip”,”rb”);
FILE *fo=fopen(“C:\\0\\cls\\b.zip”,”wb”);
fread(buf,47921,1,fp);
fwrite(buf,47921,1,fo);
fcloseall();
return 1;
}
int main(int argc, char *argv[])
{char buf[250000];
FILE *fp=fopen(“C:\\0\\cls\\sqluldr.zip”,”rb”);
FILE *fp1=fopen(“C:\\0\\cls\\sqluldrbad.zip”,”rb”);
FILE *fo=fopen(“C:\\0\\cls\\c.zip”,”wb”);
fread(buf,47921,1,fp);
fseek(fp1,47921,0);
fread(buf+47921,169361-47921,1,fp1);
fwrite(buf,169361,1,fo);
fcloseall();
return 1;
}
C:\0\cls>wget -c http://www.anysql.net/software/sqluldr.zip
–20:36:06– http://www.anysql.net/software/sqluldr.zip
=> `sqluldr.zip’
Resolving http://www.anysql.net... 75.119.205.220
Connecting to http://www.anysql.net|75.119.205.220|:80… connected.
HTTP request sent, awaiting response… 206 Partial Content
Length: 169,361 (165K), 121,440 (119K) remaining [application/zip]
100%[+++++++++++++++++++++=======================================================>] 169,361 1.11K/s ETA 00:00
20:37:26 (1.51 KB/s) – `sqluldr.zip’ saved [169361/169361]
C:\0\cls>wget -c http://www.anysql.net/software/sqluldr.zip
–21:03:34– http://www.anysql.net/software/sqluldr.zip
=> `sqluldr.zip’
Resolving http://www.anysql.net... 75.119.205.220
Connecting to http://www.anysql.net|75.119.205.220|:80… connected.
HTTP request sent, awaiting response… 200 OK
Length: 169,361 (165K) [application/zip]
39% [=============================> ] 66,390 –.–K/s ETA 01:41^
可以用
英特尔® VTune™ 性能分析器
分析
这里能用的并行, 不是指程序中片段代码(指令级)的并行执行,而是对一个查询语句, 如何透明地拆分成多个查询, 然后在程序中用多个线程或进程去执行.
如何将查询语句, 转换为等价的几个并行的语句, 这是难题.
语句并行可以通过rowid来切分,但是要设计到数据字典表的查询。一个可行的思路是通过shell脚本把切分好的语句传给ociuldr来实现并行导出
如果是手工并行,那现在多起几个导出进程就可以了.