2015-06-22 41 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