循环大量的记录
我有一个位于网络中的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规模将增长,这种方法(在我看来)不会那么有效。你能否提出一个更好的方法来做到这一点?也许拉动数据以块处理;尽管我现在不知道如何处理这个问题。
点优化:
- 创建名为类型,并使用ADO.NET读入命名的类型,而不是使用
DataSet
和DataTable
,这将减少一些内存占用。 - 只有拉你真正需要使用的记录(你不经常需要携带超过一百万条记录,但我们不知道你的业务逻辑)
问题澄清你的原职:
- 你有什么理由不能在未来扩展吗?
- 你如何处理它,你正在利用
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);
});
+1。特别是对于澄清的好处。 “(在我看来)”这篇文章中的测量并不是非常有说服力的说法,即代码需要优化(甚至可以使用Parallel.ForEach来执行潜在的I/O绑定任务)。 – 2012-07-12 23:39:13
注意这个代码中的一些东西的假设 – jcolebrand 2012-07-12 23:43:03
“SELECT * FROM z_sitemap_links”你真的需要所有的列吗? – 2012-07-12 23:28:49
绝对不要在大型数据库上做SELECT * – oleksii 2012-07-12 23:39:16
是的,表格只包含链接;没有别的 – Andrew 2012-07-12 23:47:39