Существуют ли производительность/другие недостатки при создании новых соединений RJDBC с базой данных MS SQL для каждого запроса?

Я хотел бы понять, что лучше всего подходит для (re) использования SQL-соединений к базе данных MS SQL через RJDBC.

Я могу представить три возможных сценария:

  • Хранить соединение в глобальной переменной, инициализировать один раз, использовать его везде в коде
  • Создайте новое соединение для каждого запроса
  • Сделайте что-то более сложное, например. предварительно заполнить пул открытого соединения и (повторно) использовать соединения из пула по мере необходимости.

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

Я вижу некоторые потенциальные недостатки этого подхода: производительность, налогообложение ресурсов базы данных и т.д. Но может быть, я слишком осторожен, так как R однопоточное, даже в блестящем сценарии использования?

Итак, мои конкретные вопросы:

а. Могу ли я безопасно использовать одно соединение с базой данных MS SQL через RJDBC во всем моем блестящем приложении?

В. Существуют ли какие-либо реальные недостатки (утечка памяти, производительность и т.д.) В сценарии 2 выше?


NewConnection <- function() {
  file = NULL
    # make it work on three different OSes - Linux, MacOS, Windows 
    for (path in c('/Users/victor/Documents/R/sqljdbc_3.0/enu/sqljdbc4.jar',
          '/home/oracle/sqljdbc_3.0/enu/sqljdbc4.jar',
          'C:/Projects/jdbc/sqljdbc_4.0/enu/sqljdbc4.jar')) {
      if (file.exists(path)) {
        file = path
          break
      }
    }
  if (is.null(file))
    return(NULL)
  else {
    drv <- JDBC("com.microsoft.sqlserver.jdbc.SQLServerDriver", file)
      passwd <- GetUserNamePassword()
      conn <- dbConnect(drv, "jdbc:sqlserver://sql.server.address.com", 
          passwd$username, passwd$password)
      return(conn)
  }
}

P.S. Связано: Как управлять соединением базы данных в пакете R

Ответ 1

Много вопросов:

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

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

Резюме. Если ваше приложение является простым, а не многопоточным, а не серверным приложением, чем повторное использование вашего единственного соединения. В противном случае используйте каждый раз при новом подключении или используйте пул соединений.

Ответ 2

Это может помочь рассмотреть, что происходит за кулисами каждый раз, когда вы устанавливаете соединение:

  • Необходимо установить соединение TCP/IP (включая поиск DNS и обращение к обозревателю SQL Server, чтобы получить правильный номер порта для именованного экземпляра)
  • Пользователь должен быть аутентифицирован и проверен для авторизации для подключения
  • Необходимо зарезервировать ресурсы сервера для подключения (частная память и т.д.)

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

Если ваше приложение выполняет все транзакции последовательно, вы должны открыть соединение один раз и повторно использовать его. Используйте пул соединений для многопользовательского приложения на сервере.