2010-07-09 99 views
1

有一个脚本可以从数据库中获取一堆数据,并进行迭代计算。在这个计算中有大约2500行,所以它不是一个巨大的数额,但我的老板想要我分割计算无论如何(作为一个练习)。分区大计算?

我的一般策略(我只是在黑暗中拍摄)是打数据库,抓住前50行,计算这50行的每一步,存储最后一行(因为计算是迭代),从数据库中抓取接下来的50行并继续这个过程,直到数据库中的所有行都被计入。

关于我的策略的思考?任何提示做这种事情?

+0

这将批量计算,而不是分区。那么,哪一个呢? – 2010-07-09 14:36:44

+1

我想要做我的策略所暗示的。对不起,如果我使用了错误的术语(我也有兴趣知道分割意味着什么,因为我不清楚它们之间的区别) – sooprise 2010-07-09 14:39:38

+0

对它进行分区必须有一个原因,可能是多线程。 – Dykam 2010-07-09 15:15:51

回答

1

我在编程中学到的第一件事是,当你不知道如何编写代码时,首先写出你用来自己解决它的过程(算法),一步一步,然后了解如何将其转换为代码。

听起来像是一个很好的第一步,你将写出如何解决纸上问题 - 而不用担心分区。我知道你的问题不是这么简单,但我会用一个总结的例子。

要查找所有记录的总数,您需要记录0 +记录1 +记录2 + ... +记录2499 =总和。

随着时间的推移,你可以看看它是否可以分区。另外,这很容易完成,因为添加是关联的。分组操作,这是一个分区。

现在,如果您找不到手动对计算进行分区的方法,那么尝试在代码中对其进行分区将很困难。

但是,我的第一步是手动解决它,然后在那里寻找分区的可能性。

-2

听起来像数据库cursors(可能会很慢)或while loop or other alternatives的工作。

+0

-1提及游标。 – Brian 2010-07-09 15:27:58

+0

嘿嘿......只是等待得到那个“同伴压力”徽章。 (顺便提一句,T-SQL没有像LIMIT和OFFSET这样有用的术语,这让我感到惊讶。) – ewall 2010-07-09 15:54:08

+0

T-SQL具有'top',但它确实无助于此。 T-SQL可以通过rownumber()over(按colname排序)作为row来完成分页,并使用where子句来限制返回的行。 – Brian 2010-07-09 17:45:09

0

由于计算听起来并不像它们所依赖的那样,因此这是线程提供好处的最佳示例。使N个线程为T(总记录数)/ N个记录进行计算。一旦所有线程完成后,您可以执行一个步骤来合并每个线程生成的所有小计。

+0

对不起,如果我不清楚,但计算是依赖的(这就是我的意思是迭代)......似乎我的术语在这个问题上关闭不止一次嘿嘿 – sooprise 2010-07-09 14:42:07

0

不知道计算的性质,很难说。

当人们说分区时,通常意味着数据/进程可以并行化 - 不同的分区在某种程度上是独立的 - 因此每个分区可以独立处理。

通常,我不会想到2500行,并且像这样我可能会在数据库中使用持久计算列,并在数据库中处理它,也许在重新计算行的时候触发重新计算。当然,将数据从数据库中拉出来进行计算通常可能效率低于数据库可以存储该信息或实时计算该数据的效率。

1

这是我该怎么做。

  • 奉献一个线程读取数据
  • 奉献一个线程来处理数据

,代码可能是这样的。

public class Worker 
{ 
    private BlockingQueue<Message> m_Queue = new BlockingQueue<Message>(); 

    public void Start() 
    { 
    var fetcher = new Thread(() => { Fetch(); }); 
    var processor = new Thread(() => { Process(); }); 
    fetcher.Start(); 
    processor.Start(); 
    } 

    public void Fetch() 
    { 
    while (true) 
    { 
     var packet = GetDataPacketFromDatabase(); 
     if (packet != null) 
     { 
     var message = new Message(); 
     message.Packet = packet; 
     m_Queue.Enqueue(message); 
     } 
     else 
     { 
     break; // Stop if there is nothing left to fetch. 
     } 
    } 
    } 

    public void Process() 
    { 
    while (true) 
    { 
     Message message = m_Queue.Dequeue(); 
     if (message.Packet 1= null) 
     { 
     Accumulate(message.Packet); 
     } 
     else 
     { 
     break; // Stop if there is nothing left to process. 
     } 
    } 
    } 

    private void Accumulate(Packet p) 
    { 
    // Process the packet and accumulate the results. 
    } 
} 

我要指出的是,除非你是(通过我的例子Accumulate法)做返回的数据一些严重的复杂计算,则处理线程将得到饥饿工作,大部分时间处于闲置状态。我怀疑在这种情况下,分割和并行处理的整个前提将会比一次取出所有2500行并且连续处理它们更慢。