2015-06-22 3 views
4

У меня возникают проблемы с производительностью при запуске службы Windows, в первом раунде мой lstSps длинный (около 130 хранимых процедур). Есть ли способ ускорить это (за исключением ускорения хранимых процедур)?Проблемы с производительностью, выполняющие список хранимых процедур

Когда перебег закончился и переходит во второй раунд, он идет быстрее, потому что на TimeToRun() не так много вернется. Но, моя озабоченность в первый раз, когда есть много более хранимых процедур для запуска.

У меня есть вопрос о создании массива и цикла цикла, так как я читал, что это быстрее, но я считаю, что проблема в том, что процедуры длится долго. Могу ли я построить это лучше? Может быть, использовать несколько потоков (по одному для каждого исполнения) или что-то в этом роде?

бы реально оценить некоторые советы :)

EDIT: Просто чтобы прояснить, это метод HasResult() выполняет СП: с и заставляет искать время, принимая ..

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

наилучшим подходом было бы в значительной степени зависят от того, что эти хранимые процедуры на самом деле делают, если они возвращаются тот же самый вид результирующего набора, или нет результата е или что дело, конечно, было бы полезно отправить их на SQL-сервер одновременно, а не по одному.

Причиной этого является латентность сети, если ваш SQL-сервер находится в центре обработки данных где-то, к которому вы обращаетесь через WAN, ваша латентность может быть где угодно от 200 мс. Поэтому, если вы последовательно вызываете 130 хранимых процедур, «стоимость» будет равна 200 мс X 130. Это 26 секунд, которые просто работают взад и вперед по сетевому соединению, фактически не выполняя логику в вашем proc.

Если вы можете объединить все процедуры в один звонок, вы платите 200 мс только один раз.

Выполнение их на нескольких параллельных потоках также является разумным подходом, но, как и прежде, это будет зависеть от того, что ваши процедуры делают и вернутся к вам.

Использование массива над списком на самом деле не даст вам каких-либо результатов.

Надеюсь, это поможет, удачи!

+0

SP: s возвращают XML, если у них есть хит, иначе они ничего не возвращают. Если есть хиты, тогда XML обрабатывается позже. – MrProgram

+0

Затем определенно попробуйте объединить их в один вызов SQL. – HarveySaayman

+0

Но как я могу прикрепить результат к моему объекту Sp при их одновременном выполнении? – MrProgram

Смежные вопросы