我有30Gb制表符分隔的文本文件和数字,我需要以最快的方式索引它并通过第一列和第二列对它进行查询。我已经尝试过MongoDB,但是将数据上传到数据库需要花费大量时间,我已经通过json文件尝试了mongoimport,但这需要花费大量时间。
mongoimport --upsert --upsertFields A,B,S1,E1,S2,E2 -d DBName -c TableName data.json
数据文件片段:
504 246 91.92007 93 0 4657 5631 5911 0 39 1061 1162
813 469 92.14697 109 0 2057 2665 7252 1 363 961 1399
2388 987 92.20945 61 0 1183 1575 1824 0 66 560 5088
2388 2323 92.88472 129 0 75 1161 1824 1 2516 3592 12488
2729 1008 95.29058 47 0 435 1166 1193 1 76 654 1055
2757 76 94.25837 12 0 0 44 1946 0 51 68 247
2757 2089 92.63158 14 0 12 30 1946 0 14 30 211
以最短的时间完成这项工作的正确有效方法是什么?有关最佳数据库的任何提示吗?或者关于mongo上传速度优化?
查询示例:
objs = db.TableName.find({'A':2757})
objs = db.TableName.find({'B':76})
对于A列和B列中的每个数字,最多有1000次点击,平均值为20。
答案 0 :(得分:1)
为了更加健壮,数据库通常需要完成复杂的工作。
如果使用海峡B树索引,通常会更快。
关注您将在perl中找到上传脚本。
#!/usr/bin/perl
use DB_File;
use Fcntl ;
# $DB_BTREE->{'cachesize'} = 1000000;
$DB_BTREE->{'flags'} = R_DUP ;
my (%h, %h1, %h2,$n);
my $x = tie %h, 'DB_File', "bf.db", O_RDWR|O_CREAT|O_TRUNC , 0640, $DB_BTREE;
my $x1= tie %h1, 'DB_File', "i1.db", O_RDWR|O_CREAT|O_TRUNC , 0640, $DB_BTREE;
my $x2= tie %h2, 'DB_File', "i2.db", O_RDWR|O_CREAT|O_TRUNC , 0640, $DB_BTREE;
while(<>){ chomp;
if(/(\d+)\s+(\d+)/){
$h{++$n}=$_; ## add the tup
$h1{$1} = $n; ## add to index1
$h2{$2} = $n ## add to index2;
}
}
untie %h;
untie %h1;
untie %h2;
和查询:
#!/usr/bin/perl
use DB_File;
use Fcntl ;
$DB_BTREE->{'flags'} = R_DUP ;
my (%h, %h1, %h2, $n, @list);
my $x = tie %h, 'DB_File', "bf.db", O_RDWR|O_CREAT , 0640, $DB_BTREE;
my $x1= tie %h1, 'DB_File', "i1.db", O_RDWR|O_CREAT , 0640, $DB_BTREE;
my $x2= tie %h2, 'DB_File', "i2.db", O_RDWR|O_CREAT , 0640, $DB_BTREE;
while(<>){ chomp; # Queries input format: A:number or B:number
if(/A:(\d+)/){
@list = sort $x1->get_dup($1) ;
for(@list){print $h{$_},"\n"; }
}
if(/B:(\d+)/){
@list = sort $x2->get_dup($1) ;
for(@list){print $h{$_},"\n"; }
}
}
查询非常快。
但上传花了20秒(用户时间)为1 000 000行......
(如果您对数据进行实验,请向我们展示时间)