我必须处理一个有两列和80000行的表。我需要在两个列之间对该表进行比较,这会在运行时导致system.out内存异常。
我会将第一个记录值与79,999 记录的其余部分进行比较,即(1,1),(1,2), ......(1,79999),(2,1),(2,2),......(2,79999)......(3,1),(3,2), ....(3,79999)...
如何处理这种情况
提前致谢
这是我的代码:
SqlCommand cmd = new SqlCommand("select (g.gene),n.goterm,(n.gene) from genematrix g join genematrix n on n.goterm=g.goterm where g.id<n.id", con);
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataSet ds = new DataSet();
da.Fill(ds);
表名GeneMatrix:
GoTerm Gene
1a gene1
2b gene1
1a gene2
2b gene3
等到80000记录............
上面是表结构,我将从中比较第一个基因记录和所有其他基因记录,然后进入第二个基因记录并开始将其与所有其他记录进行比较......直到最后一个基因。
当我将gene1与gene2进行比较以获得常见的术语时,结果就像
gene1 gene2 1a
gene1 gene3 2b
我的上面的查询正确地返回输出,但问题是..a system.outofmemoryexception被显示,我无法让查询完全运行直到结束。
答案 0 :(得分:0)
您应该将比较代码拆分为较小的部分,例如一次1000条记录,对这些记录进行比较,然后得到接下来的1000条记录。
您遇到的问题很可能是由于您一次抓取大量记录。
答案 1 :(得分:0)
您没有指定要比较的内容,或者如果找到匹配项,您应该做什么。
无论如何,我建议您使用the Parallel LINQ extensions。他们认真对待这样的工作,并且有很多聪明才智可以选择最好的工作方法。
答案 2 :(得分:0)
使用 DataReader 代替数据集,它将提高应用程序性能并降低系统开销。这是由于一次一行存储在内存中。在创建Command对象的实例后,通过调用Command.ExecuteReader来创建DataReader。看http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqldatareader.aspx
答案 3 :(得分:0)
您不应该使用交叉连接。最好将你的表加载到主内存中,如下所示:
SqlCommand cmd
= new SqlCommand("select g.goterm,g.gene from genematrix g ", con);
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataSet ds = new DataSet();
da.Fill(ds);
然后使用Dictionary进行比较。这里有一些“空气代码”(未经测试,未经编译,只是出于我的想法):
var d = new Dictionary<string, List<string>();
for each(var row in ds.Rows)
{
string key = (string)row["goterm"];
if(!d.ContainsKey(key))
d.Add(key, new List<string>());
d[key].Add((string)row["gene"]);
}
for each(var k in d.Keys)
{
Console.Write(k + ": ");
for each(var gene in d[k])
Console.Write(gene + " ");
Console.WriteLine();
}
(ALAS,如果这不仅仅是开箱即用,它应该会让你大致了解如何解决它。)
答案 4 :(得分:0)
检查您是否正在构建64位进程,而不是32位进程,这是Visual Studio的默认编译模式。为此,右键单击您的项目,属性 - &gt;构建 - &gt;平台目标:x64。与任何32位进程一样,以32位编译的Visual Studio应用程序的虚拟内存限制为2GB。
64位进程没有此限制,因为它们使用64位指针,因此它们的理论最大地址空间为16艾字节(2 ^ 64)。实际上,Windows x64将进程的虚拟内存限制为8TB。然后,内存限制问题的解决方案是以64位编译。
但是,默认情况下,Visual Studio中对象的大小仍限制为2GB。您将能够创建多个组合大小将大于2GB的阵列,但默认情况下不能创建大于2GB的阵列。希望如果您仍然想要创建大于2GB的数组,可以通过向app.config文件添加以下代码来实现:
<configuration>
<runtime>
<gcAllowVeryLargeObjects enabled="true" />
</runtime>
</configuration>
答案 5 :(得分:0)
我认为你没有正确地描述你的问题。您从一个包含2列的表开始,但您的代码段会加载包含3列的联接。
请显示导致OutOfMemory异常的行。
理论1。 运行计数查询:从n.goterm = g.goterm中的genematrix g join genematrix n中选择count(g.gene),其中g.id
理论2。 如果加载记录是问题,那么我认为你在代码中构建80000 * 80000数组。即使您的条目只有一个字节,80000 * 80000b = 6400000000b = 5.9GB,这更多.Net'单个对象2GB'限制。