2015-06-22 38 views
4

我在啓動Windows服務時遇到了一些性能問題,第一輪我的lstSps很長(大約130個存儲過程)。無論如何要加快速度(除了加速存儲過程)?性能問題正在執行存儲過程列表

當foreach結束並轉到第二輪時,它會更快,因爲在TimeToRun()上沒有那麼多返回true。但是,我關心的是第一次,當有更多的存儲過程運行時。

雖然我已經做了一個數組和for循環,因爲我讀得更快,但我相信問題是因爲程序需要很長時間。我可以以更好的方式建立這個嗎?也許使用多個線程(每個執行一個)或類似的東西?

真的很感激一些提示:)

編輯:只是爲了澄清,它的方法HasResult()正在執行SP:S和讓看花時間..

lock (lstSpsToSend) 
{ 
    lock (lstSps) 
    { 
     foreach (var sp in lstSps.Where(sp => sp .TimeToRun()).Where(sp => sp.HasResult())) 
     { 
      lstSpsToSend.Add(sp); 
     } 
    } 
} 

while (lstSpsToSend.Count > 0) 
{ 
    //Take the first watchdog in list and then remove it 
    Sp sp; 
    lock (lstSpsToSend) 
    { 
     sp = lstSpsToSend[0]; 
     lstSpsToSend.RemoveAt(0); 
    } 

    try 
    { 
     //Send the results 
    } 
    catch (Exception e) 
    { 
     Thread.Sleep(30000); 
    } 
} 
+0

只要你沒有分析它,我們不能幫你實現...... –

+0

我想要的幫助不是加速所有存儲過程,但找到一個更好的方式來執行它們,所以我不有做1.執行所有存儲過程(等到所有完成)2.開始處理結果 – MrProgram

回答

1

我會做的是這樣的:

int openThread = 0; 
ConcurrentQueue<Type> queue = new ConcurrentQueue<Type>(); 
foreach (var sp in lstSps) 
{ 
    Thread worker = new Thread(() => 
     { 
      Interlocked.Increment(ref openThread); 
      if(sp.TimeToRun() && sp.HasResult) 
      { 
       queue.add(sp); 
      } 
      Interlocked.Decrement(ref openThread); 
     }) {Priority = ThreadPriority.AboveNormal, IsBackground = false}; 
     worker.Start(); 
} 
// Wait for all thread to be finnished 
while(openThread > 0) 
{ 
    Thread.Sleep(500); 
} 

// And here move sp from queue to lstSpsToSend 

while (lstSpsToSend.Count > 0) 
{ 
    //Take the first watchdog in list and then remove it 
    Sp sp; 
    lock (lstSpsToSend) 
    { 
     sp = lstSpsToSend[0]; 
     lstSpsToSend.RemoveAt(0); 
    } 

    try 
    { 
     //Send the results 
    } 
    catch (Exception e) 
    { 
     Thread.Sleep(30000); 
    } 
} 
+0

不太確定你在那裏做了什麼,你是否爲每個SP創建一個新的線程?爲什麼這應該提高性能? – MrProgram

+0

你說這是'TimeToRun()'放慢你的東西,如果你把它放在不同的線程上,讓系統並行化計算,你將節省時間。我也可以使用'Parallel.ForEach'。但也許我*完全*誤讀了這個問題...... @krillezzz –

+0

對不起,不夠清楚。它是HasResult()執行SP:s並且循環花費時間。 – MrProgram

0

最好的辦法很大程度上靠的是什麼將這些存儲過程實際上做,如果他們正在返回同一種結果集的,或者沒有結果f或者那個問題,將它們一次全部發送到SQL服務器而不是一次一定是有益的。

原因是網絡延遲,如果您的SQL服務器位於您通過WAN訪問的某個數據中心的某個位置,則您的延遲可能在200毫秒以上的任何位置。因此,如果您按順序調用130個存儲過程,則「成本」將爲200ms X 130.這是26秒,只是通過網絡連接來回運行,而不是實際執行proc中的邏輯。

如果您可以將所有的程序合併爲一個通話,您只需支付一次200ms的費用。

在多個併發線程上執行它們也是一種合理的方法,但是和以前一樣,這取決於你的過程在做什麼並返回給你。

在列表中使用數組並不會真的提高性能。

希望這會有所幫助,祝你好運!

+0

SP:如果它們有命中,則返回XML,否則它們不返回任何內容。如果有一個命中,那麼稍後會處理XML。 – MrProgram

+0

然後絕對嘗試將它們合併爲一個SQL調用。 – HarveySaayman

+0

但是,如何一次性將所有結果附加到我的Sp對象? – MrProgram