Производительность цикла Linq to SQL - PullRequest
4 голосов
/ 21 сентября 2011

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

Исходный код, который я использовал, был следующим:

foreach(var obj in MyObjects)
{
    using(var connection = new LinqToSqlDBContext())
    {
        connection.StoredProc1(obj.Name);
        connection.StoredProc2(obj.Name);
        connection.SubmitChanges();
    }
}

Я полагаю, что это будет более эффективным:

using(var connection = new LinqToSqlDBContext())
{
    foreach(var obj in MyObjects)
    {
        connection.StoredProc1(obj.Name);
        connection.StoredProc2(obj.Name);       
    }
    connection.SubmitChanges();
}

Есть ли лучший способ сделать это для повышения производительности?Я использую классы Linq to SQL и C # 4.0.

Спасибо!

Ответы [ 5 ]

4 голосов
/ 21 сентября 2011

Поскольку вы вызываете хранимые процедуры, но не выполняете изменения объекта, SubmitChanges() является избыточным.При нормальном использовании я бы ожидал, что это SubmitChanges будет существенным фактором, поэтому важно сбалансировать количество вызовов и размер отдельных транзакций.Однако, это здесь не применимо , поэтому я бы просто использовал:

using(var connection = new LinqToSqlDBContext())
{
    foreach(var obj in MyObjects)
    {
        connection.StoredProc1(obj.Name);
        connection.StoredProc2(obj.Name);       
    }
}
2 голосов
/ 21 сентября 2011

Как всегда - зависит .

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

Второй блок кода, однако, выполняет хранимые процедуры ... и затем фиксирует все изменения за один раз, за ​​одну транзакцию.

Это может быть более эффективным, в зависимости от вашего приложения.

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

Обратите внимание, что на практике обычно небольшие издержки связаны с открытием и закрытием соединений, поскольку они обычно кэшируются в пуле соединений. Итак, производительность

using(var connection = new LinqToSqlDBContext())
{
    foreach(var obj in MyObjects)
    {
        connection.StoredProc1(obj.Name);
        connection.StoredProc2(obj.Name);       
    }
}

и

foreach(var obj in MyObjects)
{
    using(var connection = new LinqToSqlDBContext())
    {
        connection.StoredProc1(obj.Name);
        connection.StoredProc2(obj.Name);
    }
}

, скорее всего, будет очень похоже.

2 голосов
/ 21 сентября 2011

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

2 голосов
/ 21 сентября 2011

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

0 голосов
/ 21 сентября 2011

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

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

Также сделайте так, как говорит Джонас Х: предоставьте список имен и вызовите SP один раз.

И, возможно, вы можете выполнить некоторую параллельную обработку, вызвав все SP в другом потоке, но этогде Марк Гравелл мог бы пролить свет?

...