循环大量的记录

问题描述:

我有一个位于网络中的postgre服务器,我正在使用数据库。 我需要经过大量的记录(1mil +),每个选择都需要时间。循环大量的记录

这是我目前的方法:

DataSet ds = new psqlWork().getDataSet("SELECT * FROM z_sitemap_links"); 
DataTable dt = ds.Tables[0]; 
Parallel.ForEach(dt.AsEnumerable(), dr => 
{ 
    new Sitemap().runSitemap(dr[1].ToString(), counter); 
    counter++; 
}); 

但当DB规模将增长,这种方法(在我看来)不会那么有效。你能否提出一个更好的方法来做到这一点?也许拉动数据以块处理;尽管我现在不知道如何处理这个问题。

+4

“SELECT * FROM z_sitemap_links”你真的需要所有的列吗? – 2012-07-12 23:28:49

+0

绝对不要在大型​​数据库上做SELECT * – oleksii 2012-07-12 23:39:16

+0

是的,表格只包含链接;没有别的 – Andrew 2012-07-12 23:47:39

点优化:

  • 创建名为类型,并使用ADO.NET读入命名的类型,而不是使用DataSetDataTable,这将减少一些内存占用。
  • 只有拉你真正需要使用的记录(你不经常需要携带超过一百万条记录,但我们不知道你的业务逻辑)

问题澄清你的原职:

  • 你有什么理由不能在未来扩展吗?
  • 你如何处理它,你正在利用Parallel.ForEach?假设底层系统具有这种能力,那么您现在的方法可能会很好。考虑一下,你应该描述实际的表现,而不是猜测会发生什么。
DataSet ds = new psqlWork().getDataSet(@" 
    SELECT * FROM z_sitemap_links 
    order by timestamp asc /*always order when skipping records so you get the same skips */ 
    LIMIT 100000 /* using these two with variables you could skip so many records /* 
    OFFSET 100000 /* depending on what you're aiming for */ 
"); 
DataTable dt = ds.Tables[0]; 
Parallel.ForEach(dt.AsEnumerable(), dr => 
{ 
    new Sitemap().runSitemap(dr[1].ToString(), counter); 
    counter++; 
}); 

而且,如果你可以利用这样的事:row_number() OVER (ORDER BY col1) AS i,那么你可以跳过柜台,因为这将是提供给你,你选择行回来了,但我的Postgres的知识没有按”告诉我,如果这将是1..100000每次从上面的代码,或者如果它将是你想要的,但在Database Administrators肯定知道的家伙。这意味着你的代码将变为:

Parallel.ForEach(recordList, record => 
{ 
    new Sitemap().runSitemap(record.FieldYouNeed, record.RowNumberFromDatabase); 
}); 
+0

+1。特别是对于澄清的好处。 “(在我看来)”这篇文章中的测量并不是非常有说服力的说法,即代码需要优化(甚至可以使用Parallel.ForEach来执行潜在的I/O绑定任务)。 – 2012-07-12 23:39:13

+0

注意这个代码中的一些东西的假设 – jcolebrand 2012-07-12 23:43:03