ADO.Net: повторно использовать SqlConnection или каждый раз получать новый?

Прежде чем отправлять этот вопрос, я прочитал несколько ответов на этом сайте: этого . Все, похоже, согласны с тем, что «пулы приложений C# оптимизированы для нескольких вызовов в одну и ту же базу данных».

Тем не менее, я по-прежнему наблюдаю существенное снижение производительности, если получаю соединение из пула. Вот мои ориентиры:

    private const string localConnString = "Data Source=(local);Integrated Security=SSPI;database=MyTest;Pooling=true";


    [Test]
    public void GetNewConnectionEveryTime()
    {
        var stopwatch = new Stopwatch();
        stopwatch.Start();
        for (var i = 0; i < 1000; i++)
        {
            using (var conn = new SqlConnection(localConnString))
            {
                conn.Open();
                const string saveTrancount = "EXEC dbo.TestTran";
                ExecuteSql(conn, saveTrancount);
            }
        }
        stopwatch.Stop();
        Console.WriteLine("Time elapsed: {0}", stopwatch.Elapsed);
        //Time elapsed: 00:00:00.5576016
    }

    [Test]
    public void ReuseOneConnection()
    {
        var stopwatch = new Stopwatch();
        stopwatch.Start();
        using (var conn = new SqlConnection(localConnString))
        {
            conn.Open();
            for (var i = 0; i < 1000; i++)
            {
                const string saveTrancount = "EXEC dbo.TestTran";
                ExecuteSql(conn, saveTrancount);
            }
        }
        stopwatch.Stop();
        Console.WriteLine("Time elapsed: {0}", stopwatch.Elapsed);
        //Time elapsed: 00:00:00.1110324
    }

    private void ExecuteSql(SqlConnection conn, string sql, int timeout = 0)
    {
        var command = conn.CreateCommand();
        command.CommandText = sql;
        command.CommandType = CommandType.Text;
        command.CommandTimeout = timeout;
        command.ExecuteNonQuery();
    }

Очевидно, что получение соединения из пула занимает в четыре раза больше времени (00: 00: 00.5576016 - 00: 00: 00.1110324 appr 0.44), чем выполнение фактической работы (00: 00: 00.1110324 во втором эталоном). Что мне не хватает?

Изменить: Я запускаю эти тесты против базы данных, созданной на RAM Disk, поэтому все мои операции с базой данных выполняются очень быстро.

4
nl ja de

2 ответы

Тебе нужны тесты. Было бы еще хуже, если бы вы открыли и закрыли соединение для каждой итерации без объединения пулов, но это совсем другая история. Однако, когда вы закрываете объединенное соединение, вы вместо этого возвращаете его в пул: под обложками SNAC выдает sp_reset_connection и помещает соединение обратно в пул. Как правило, это очень быстрая операция (если не блокировать пинки), но она должна принимать небольшое, но ненулевое время. Повторное использование того же соединения без закрытия и открытия для каждой итерации позволяет избежать этого небольшого запаздывания. Однако, если бы вы сравнили использование same объединенных и не объединенных соединений, это имело бы для меня больше смысла. Вы пробовали это?

Here's an interesting post on sp_reset_connection

4
добавлено
+1 Ваш ответ и ссылка полезны. Что касается вашего вопроса, я, конечно, мог бы «сравнить то же использование объединенных и не объединенных соединений», но почему это интересно? Обычно я использую объединение пулов. Существуют ли какие-либо сценарии, когда я должен отключить его?
добавлено автор A-K, источник
@StrayCatDBA существует множество обновлений надежности платформы .net. Какой из них вы использовали?
добавлено автор A-K, источник
Существует обновление надежности платформы .net, которое вызывает проверку, чтобы убедиться, что соединение все еще хорошо, прежде чем повторно использовать его. если соединение плохое, оно будет открыто открыто. Это необходимо для sql azure.
добавлено автор StrayCatDBA, источник
> Есть ли какие-либо сценарии, когда я должен отключить его? Может быть. С отказоустойчивой кластеризацией и зеркалированием базы данных вы можете заканчивать работу с неверными подключениями в вашем пуле после сбоя. Вместо того, чтобы полностью отключить пул, вы можете сбросить пул. Не знаю, отвечает ли он на ваш вопрос.
добавлено автор spaghettidba, источник
Это отличная информация! Спасибо, что поделился.
добавлено автор spaghettidba, источник

+1 к @spaghettidba - согласен, а также добавить комментарии .....

Мой подход в прошлом заключался в том, чтобы использовать одно и то же соединение несколько раз - за исключением того, что даже каждый раз, когда я всегда принимал (не измерял), чтобы подключиться к пулу соединений, чтобы получить соединение, стоимость some как сказал @spaghettidba.

Основным преимуществом производительности пула является сценарий, когда он не имеет смысла/не может повторно использовать один и тот же экземпляр подключения - в этом случае получение ранее использованного соединения из пула происходит намного быстрее, поскольку на самом деле оно не требуется уйти и фактически попытаться подключиться к серверу, он просто предполагает, что он есть и доступен - т.е. connection.Open() по моему опыту не является ошибкой для объединенного соединения, даже если сервер не работает - это будет просто ошибка при попытке выполнить что-либо против соединения.

1
добавлено
+1 yes, connection.Open() не вызывает никакой активности, которую я могу наблюдать в Profiler. Я буду видеть sp_reset_connection, когда я запускаю команду против моего повторно используемого соединения.
добавлено автор A-K, источник
DotNetRuChat
DotNetRuChat
2 992 участник(ов)

Чат русскоязычного .NET сообщества http://dotnet.ru/ Вам могут быть интересны: @dotnetchat, @cilchat, @fsharp_chat, @pro_net, @xamarin_russia, @microsoftstackjobs, @uwp_ru Флуд в @dotnettalks

Microsoft Stack Jobs
Microsoft Stack Jobs
1 788 участник(ов)

Work & freelance only Microsoft Stack. Feed https://t.me/Microsoftstackjobsfeed Чат про F#: @Fsharp_chat Чат про C#: @CSharpChat Чат про Xamarin: @xamarin_russia Чат общения:@dotnettalks

SqlCom.ru - Стиль жизни SQL
SqlCom.ru - Стиль жизни SQL
908 участник(ов)

Правила чата - https://t.me/sqlcom/88269 @sqlcom - основной канал (только MS SQL) @sql_ninja - второй канал (SQL вопросы начального уровня и свободное общение) @Gopnegbot - Викторина по SQL Server (наберите в привате /quiz). Предложения в @sql_ninja

pro.net
pro.net
710 участник(ов)

Обсуждение .NET Framework и всего, что с ним связано. Правила: не флудить не по теме, уважать ваших коллег и никакой рекламы (объявления о вакансиях можно согласовать с @AlexFails). Флудилка: @dotnettalks Участник @proDOT

Microsoft Developer Community Chat
Microsoft Developer Community Chat
584 участник(ов)

Чат для разработчиков и системных администраторов Microsoft Developer Community. __________ Новостной канал: @msdevru __________ Баним за: оскорбления, мат, рекламу, флуд, флейм, спам, NSFW контент, а также большое количество оффтоп тем. @banofbot

.NET Talks: Force Push Masters
.NET Talks: Force Push Masters
490 участник(ов)

Свободный чат .NET разработчиков. Правила: t.me/dotnettalks/56823 Вам могут быть интересны: @dotnetruchat, @dotnetchat, @cilchat, @fsharp_chat, @pro_net, @dotnetgroup, @xamarin_russia, @microsoftstackjobs, @uwp_ru http://combot.org/chat/-1001128250813

SQL_Ninja
SQL_Ninja
340 участник(ов)

Правила чата - https://t.me/sqlcom/88269 @sqlcom - основной канал (только SQL) @sql_ninja - второй канал (SQL вопросы начального уровня и свободное общение) @Gopnegbot - Викторина по SQL Server (наберите в привате /quiz)

.NET Chat Убежище
.NET Chat Убежище
246 участник(ов)

Чат .NET разработчиков под эгидой MSK/SPB .NET Community Group Вам могут быть интересны: @fsharp_chat, @dotnetruchat, @cilchat, @xamarin_russia, @microsoftstackjobs, @dotnetgroup Флуд в @dotnettalks

.NET CIL Chat
.NET CIL Chat
54 участник(ов)

.NET CIL (aka IL aka MSIL)