正常情況下,判斷數據集中是否出現id
的最快方法是使用散列法,因此我將使用id
作爲關鍵字並將其餘列的MD5校驗和或CRC作爲存儲在那把鑰匙。如果你的數據有很多列,這應該可以緩解內存壓力。我爲什麼這麼想?因爲你說你有數百萬條記錄的GB數據,所以我推斷每條記錄的大小必須是千字節的數量 - 即相當寬。
所以,我能合成的在Perl 13M舊值的哈希和15M新值的哈希,然後找到添加,更改,如下面取出。
#!/usr/bin/perl
use strict;
use warnings;
# Set $verbose=1 for copious output
my $verbose=0;
my $million=1000000;
my $nOld=13*$million;
my $nNew=15*$million;
my %oldHash;
my %newHash;
my $key;
my $cksum;
my $i;
my $found;
print "Populating oldHash with $nOld entries\n";
for($i=1;$i<=$nOld;$i++){
$key=$i-1;
$cksum=int(rand(2));
$oldHash{$key}=$cksum;
}
print "Populating newHash with $nNew entries\n";
$key=$million;
for($i=1;$i<=$nNew;$i++){
$cksum=1;
$newHash{$key}=$cksum;
$key++;
}
print "Part 1: Finding new ids (present in newHash, not present in oldHash) ...\n";
$found=0;
for $key (keys %newHash) {
if(!defined($oldHash{$key})){
print "New id: $key, cksum=$newHash{rkey}\n" if $verbose;
$found++;
}
}
print "Total new: $found\n";
print "Part 2: Finding changed ids (present in both but cksum different) ...\n";
$found=0;
for $key (keys %oldHash) {
if(defined($newHash{$key}) && ($oldHash{$key}!=$newHash{$key})){
print "Changed id: $key, old cksum=$oldHash{$key}, new cksum=$newHash{$key}\n" if $verbose;
$found++;
}
}
print "Total changed: $found\n";
print "Part 3: Finding deleted ids (present in oldHash, but not present in newHash) ...\n";
$found=0;
for $key (keys %oldHash) {
if(!defined($newHash{$key})){
print "Deleted id: $key, cksum=$oldHash{$key}\n" if $verbose;
$found++;
}
}
print "Total deleted: $found\n";
這需要53秒在我的iMac上運行。
./hashes
Populating oldHash with 13000000 entries
Populating newHash with 15000000 entries
Part 1: Finding new ids (present in newHash, not present in oldHash) ...
Total new: 3000000
Part 2: Finding changed ids (present in both but cksum different) ...
Total changed: 6000913
Part 3: Finding deleted ids (present in oldHash, but not present in newHash) ...
Total deleted: 1000000
出於測試的目的,我從0..12,999,999在oldHash
運行鍵和按鍵在newHash
運行從1,000,000..16,000,000那麼我可以很容易地知道,如果它的工作,因爲新的鍵應該是13,000,000..16,000,000和刪除的鍵應該是0..999,999。我也使checksums
在0和1之間交替,這樣50%的重疊ID應該看起來不同。
已經在一個相對簡單的方式來完成它,現在我可以看到,你只需要校驗部分找到改變的ID,這樣你就可以做1部分和第3無校驗以節省內存。在加載數據時,您也可以一次執行第2部分的一個元素,因此您不需要將所有舊的和所有新的ID都預先加載到內存中。相反,當您將另一組ID傳輸到內存中時,您將加載較小的舊數據集和新數據集,然後逐個檢查一個ID是否更改,這會降低對內存的要求。最後,如果這種方法有效,它可以很容易地在C++中重新完成,例如,進一步加快速度並進一步減少內存需求。
我正在考慮將獨特的id讀入兩個Perl哈希中 - 一個用於舊的舊哈希,另一個可能是每個記錄的剩餘字段的CRC/SHA校驗和作爲存儲在哈希中的項目。檢查通用/獨特的會員資格應該非常快。嘗試添加一個Perl標籤也許。 –
你提到過關於文件大小。我可以知道速度是多少?意思是,你多久會得到這個後續文件。 –
每天約20K次 – user5121292