Открытие соединения с базой данных один раз или для каждой операции с базой данных? - PullRequest
3 голосов
/ 04 марта 2009

В настоящее время я создаю веб-портал с ASP.NET, который в значительной степени зависит от использования базы данных. По сути, каждый (почти каждый: P) GET-запрос любого пользователя приводит к запросу к базе данных с веб-сервера.

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

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

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

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

Ответы [ 9 ]

8 голосов
/ 04 марта 2009

Вы слишком рано беспокоиться о производительности.

Так или иначе, соединения объединяются фреймворком. Вы должны открыть их, использовать их и утилизировать как можно скорее.

Что-то вроде ...

public object Load()
{
  using (SqlConnection cn = new SqlConnection(connectionString))
  using (SqlCommand cm = new SqlCommand(commandString, cn))
  {
    cn.Open();
    return cm.ExecuteScalar();
  }
}
3 голосов
/ 04 марта 2009

Лучше позволить ADO.NET обрабатывать пулы соединений. Он сохранит соединение, если сочтет это необходимым, но не использует статический объект соединения. Это просто пахнет. Было бы лучше передать объект соединения методам, которые в нем нуждаются, и создать соединение в блоке using.

1 голос
/ 04 марта 2009

Я бы больше думал о кэшировании, чем о расширенном пуле соединений. Каждое получение требует попадания в базу данных?

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

1 голос
/ 04 марта 2009

Вы всегда должны закрывать соединение после завершения взаимодействия с БД. ADO.NET имеет пул соединений, который позаботится об эффективном повторном использовании соединений. Всякий раз, когда вы открываете 2-е, 3-е и последующие подключения - они будут взяты из пула почти без затрат.

Надеюсь, это поможет.

0 голосов
/ 04 марта 2009

Действительно, первый вопрос, который нужно задать, это , почему вы так сильно беспокоитесь о производительности? Какова ваша ожидаемая нагрузка? Вы уже пробовали это?

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

0 голосов
/ 04 марта 2009

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

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

0 голосов
/ 04 марта 2009

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

0 голосов
/ 04 марта 2009

Вы определенно не хотите открывать соединение для каждого вызова базы данных, что очень быстро приведет к крайне низкой производительности. Создание подключения к базе данных очень дорого.

Вместо этого вам следует использовать пул соединений. Пул будет управлять вашими соединениями и, по возможности, попытаться повторно использовать существующие соединения.

0 голосов
/ 04 марта 2009

ADO.NET делает пул соединений. Когда вы вызываете close для объекта соединения, он будет поддерживать соединение в пуле, делая следующее соединение намного быстрее.

...