2010-07-09 93 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行並且連續處理它們更慢。