【发布时间】:2014-02-14 01:44:56
【问题描述】:
我正在从事一个 Perl 项目,该项目涉及使用大约 1700 万个键构建散列。这太大了,无法存储在内存中(我的笔记本电脑的内存只能保存大约 1000 万个键)。我知道解决方案是将数据存储在磁盘上,但在实践中我无法执行此操作。这是我尝试过的:
DB_File
use strict;
use DB_File;
my $libfile = shift;
my %library;
tie %library, "DB_File", "$libfile";
for (my $a = 1; $a < 17000000; a++) {
# Some code to generate key and value #
$library{$key} = $value;
}
这给了我一个分段错误:循环中的 11 部分,原因我不明白。
伯克利数据库
use strict;
use BerkeleyDB;
my $libfile = shift;
my $library = new BerkeleyDB::Hash
-Filename => $libfile,
-Flags => DB_CREATE;
for (my $a = 1; $a < 17000000; a++) {
# Some code to generate key and value #
$library->db_put($key, $value);
}
这对于前 1500 万个键似乎效果很好,但随后会显着减慢并最终在循环结束时完全冻结。我认为这不是内存问题。如果我将循环分成四部分,将它们放在四个单独的程序中,并按顺序运行它们(每次向数据库添加约 400 万条记录),前三个成功完成,但第四个在数据库大约有 15 条时挂起万把钥匙。所以看起来 BerkeleyDB 可能只能处理大约 1500 万个哈希键???
DBM::Deep
use strict;
use DBM::Deep;
my $libfile = shift;
my $library = new DBM::Deep $libfile;
for (my $a = 1; $a < 17000000; a++) {
# Some code to generate key and value #
$library->put($key => $value);
}
从初步测试来看,这似乎工作正常,但它真的很慢:每千个键大约 5 秒,或者运行整个循环约 22 小时。如果可能的话,我宁愿避免这种情况。
我将非常感谢有关解决其中一个软件包的建议,或有关完成相同任务的其他选项的想法。
更新
【问题讨论】:
-
看看使用 mongodb 之类的 nosql 数据库是否适合您。 mongodb.com/learn/nosql
-
什么操作系统和 perl 版本以及您尝试过的模块?您的平均键和平均值有多大?
-
你能在“key sorted”模式下生成条目吗?我想我记得一个巨大的 BerkeleyDB 案例,当从散列切换到 btree 时,“键排序”插入提高了性能。改进非常显着,但还不够。
-
@AndrzejA.Filip:使用 Btree 就可以了。谢谢!!!
-
在报告的情况下,我记得巨大的 BerkeleyDB 创建时间从哈希的几个小时减少到带有“键排序”附加的 btree 的 20 分钟。反正时间太长了,所以这个家伙决定切换到能够直接访问 SQL 数据库的软件,以避免将 SQL 数据库“转储”到 BerkeleyDB。
标签: database perl hash berkeley-db tie