Database 将一大组数据与另一大组数据进行比较的最快方法是什么?
你有一个独特项目的大列表(数十万行)。您希望查看这些项是否存在于另一组数据中。另一组数据只是一个逐行包含项目的文件,也是一组唯一的数据。您可以将任何数据放入数据库,使用任何编程语言等 你怎么比较这些最快的呢?唯一的限制是硬件是普通服务器,而不是db服务器。最多一个主轴 C?实现排序算法?数据库用于索引等Database 将一大组数据与另一大组数据进行比较的最快方法是什么?,database,sorting,dataset,compare,Database,Sorting,Dataset,Compare,你有一个独特项目的大列表(数十万行)。您希望查看这些项是否存在于另一组数据中。另一组数据只是一个逐行包含项目的文件,也是一组唯一的数据。您可以将任何数据放入数据库,使用任何编程语言等 你怎么比较这些最快的呢?唯一的限制是硬件是普通服务器,而不是db服务器。最多一个主轴 C?实现排序算法?数据库用于索引等 管理员拿出了我的答案“因为问题太广泛”:python中的Bloom过滤器。使用python的bloom filter库很容易实现。您可以使用一个简单的bash脚本: 首先对列表进行排序 $ so
管理员拿出了我的答案“因为问题太广泛”:python中的Bloom过滤器。使用python的bloom filter库很容易实现。您可以使用一个简单的bash脚本: 首先对列表进行排序
$ sort list1.txt > list1.sorted.txt
$ sort list2.txt > list2.sorted.txt
然后执行联接以查找两个列表的公共元素:
$ join -1 1 -2 1 list1.sorted.txt list2.sorted.txt
这应该相对较快,并且内存消耗较低 您可以使用一个简单的bash脚本: 首先对列表进行排序
$ sort list1.txt > list1.sorted.txt
$ sort list2.txt > list2.sorted.txt
然后执行联接以查找两个列表的公共元素:
$ join -1 1 -2 1 list1.sorted.txt list2.sorted.txt
这应该相对较快,并且内存消耗较低 如果您的“测试”文件大小合理,一个快速解决方案是为该文件中的每个条目构建一个哈希映射。C#解决方案(在大O(N)中运行)如下:
public static bool SetIsPresentIn(string firstFileLocation, string secondFileLocation)
{
HashSet<string> set = new HashSet<string> ();
using (var sr = new FileStream(firstFileLocation, FileMode.Open, FileAccess.Read))
{
using (var reader = new StreamReader(sr))
{
while (reader.EndOfStream == false )
{
var text = reader.ReadLine();
set.Add(text);
}
}
}
// iterating through the first one!
using (var secondFile = new FileStream(secondFileLocation, FileMode.Open, FileAccess.Read))
{
using (var reader = new StreamReader(secondFile))
{
while (reader.EndOfStream == false)
{
var line = reader.ReadLine();
// perform a lookup!
if (set.Remove(line) && set.Count == 0)
return true;
}
}
}
return set.Count == 0;
}
publicstaticboolsetispresentin(stringfirstfilelocation,stringsecondfilelocation)
{
HashSet=newhashset();
使用(var sr=newfilestream(firstFileLocation,FileMode.Open,FileAccess.Read))
{
使用(变量读取器=新的流读取器(sr))
{
while(reader.EndOfStream==false)
{
var text=reader.ReadLine();
添加(文本);
}
}
}
//迭代第一个!
使用(var secondFile=new FileStream(secondFileLocation,FileMode.Open,FileAccess.Read))
{
使用(var reader=newstreamreader(secondFile))
{
while(reader.EndOfStream==false)
{
var line=reader.ReadLine();
//执行查找!
if(set.Remove(line)&&set.Count==0)
返回true;
}
}
}
返回集。计数==0;
}
否则,我会做一件聪明的事情:在文件分区中分割“测试”文件:每个分区名称与每行的哈希代码匹配。当在第二个文件上迭代时,只需创建一个哈希代码并在从第一个文件构建的共同响应分区内进行搜索
例如:
public static bool SetIsPresentInUsingFilePartitions(string firstFileLocation, string secondFileLocation, string partitionsRootLocation)
{
Dictionary<int, StreamWriter> partitionWriters = new Dictionary<int, StreamWriter>();
Dictionary<int, string> locations = new Dictionary<int, string>();
using (var sr = new FileStream(secondFileLocation, FileMode.Open, FileAccess.Read))
{
using (var reader = new StreamReader(sr))
{
while (reader.EndOfStream == false)
{
var text = reader.ReadLine();
var hCode = text.GetHashCode();
var fileName = Path.Combine(partitionsRootLocation, hCode.ToString ());
if (false == partitionWriters.ContainsKey(hCode))
{
var fs = new FileStream(fileName, FileMode.Create, FileAccess.ReadWrite);
partitionWriters[hCode] = new StreamWriter(fs);
locations[hCode] = fileName;
}
partitionWriters[hCode].WriteLine(text);
}
}
}
// close writers
foreach (var item in partitionWriters)
item.Value.Dispose();
using (var sr = new FileStream(firstFileLocation, FileMode.Open, FileAccess.Read))
{
using (var reader = new StreamReader(sr))
{
while (reader.EndOfStream == false)
{
var line = reader.ReadLine();
var hCode = line.GetHashCode();
string location;
if (false == locations.TryGetValue(hCode, out location))
{
return false; // tere's a line that is not found in the second file!
}
var found = false;
using (var file = new FileStream(location, FileMode.Open, FileAccess.Read))
{
using (var fs = new StreamReader(file))
{
while (fs.EndOfStream == false)
{
var firstFileLine = fs.ReadLine();
if (line == firstFileLine)
{
found = true;
break;
}
}
}
}
if (!found)
return false;
}
}
}
return true;
}
publicstaticboolsetispresentingfilepartitions(stringfirstfilelocation、stringsecondfilelocation、stringpartitionsrootlocation)
{
Dictionary partitionWriters=新建字典();
字典位置=新字典();
使用(var sr=new FileStream(secondFileLocation,FileMode.Open,FileAccess.Read))
{
使用(变量读取器=新的流读取器(sr))
{
while(reader.EndOfStream==false)
{
var text=reader.ReadLine();
var hCode=text.GetHashCode();
var fileName=Path.Combine(partitionsRootLocation,hCode.ToString());
if(false==partitionWriters.ContainsKey(hCode))
{
var fs=new FileStream(文件名,FileMode.Create,FileAccess.ReadWrite);
分区编写器[hCode]=新的流编写器(fs);
位置[hCode]=文件名;
}
分区编写器[hCode].WriteLine(文本);
}
}
}
//亲密作家
foreach(PartitionWriter中的变量项)
item.Value.Dispose();
使用(var sr=newfilestream(firstFileLocation,FileMode.Open,FileAccess.Read))
{
使用(变量读取器=新的流读取器(sr))
{
while(reader.EndOfStream==false)
{
var line=reader.ReadLine();
var hCode=line.GetHashCode();
字符串位置;
if(false==locations.TryGetValue(hCode,out位置))
{
return false;//这是第二个文件中找不到的一行!
}
var=false;
使用(var file=newfilestream(位置,FileMode.Open,FileAccess.Read))
{
使用(var fs=newstreamreader(文件))
{
while(fs.EndOfStream==false)
{
var firstFileLine=fs.ReadLine();
if(line==firstFileLine)
{
发现=真;
打破
}
}
}
}
如果(!找到)
返回false;
}
}
}
返回true;
}
如果您的“测试”文件大小合理,一个快速解决方案是为该文件中的每个条目构建一个哈希映射。C#解决方案(在大O(N)中运行)如下:
public static bool SetIsPresentIn(string firstFileLocation, string secondFileLocation)
{
HashSet<string> set = new HashSet<string> ();
using (var sr = new FileStream(firstFileLocation, FileMode.Open, FileAccess.Read))
{
using (var reader = new StreamReader(sr))
{
while (reader.EndOfStream == false )
{
var text = reader.ReadLine();
set.Add(text);
}
}
}
// iterating through the first one!
using (var secondFile = new FileStream(secondFileLocation, FileMode.Open, FileAccess.Read))
{
using (var reader = new StreamReader(secondFile))
{
while (reader.EndOfStream == false)
{
var line = reader.ReadLine();
// perform a lookup!
if (set.Remove(line) && set.Count == 0)
return true;
}
}
}
return set.Count == 0;
}
public static bool SetIsPresentIn(字符串firstFileLocatio